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 #include "precompiled.hpp"
26 #include "classfile/moduleEntry.hpp"
27 #include "classfile/packageEntry.hpp"
28 #include "logging/log.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "oops/symbol.hpp"
31 #include "runtime/handles.inline.hpp"
32 #include "utilities/events.hpp"
33 #include "utilities/growableArray.hpp"
34 #include "utilities/hashtable.inline.hpp"
35 #include "utilities/ostream.hpp"
36
37 // Returns true if this package specifies m as a qualified export, including through an unnamed export
38 bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
39 assert(Module_lock->owned_by_self(), "should have the Module_lock");
40 assert(m != NULL, "No module to lookup in this package's qualified exports list");
41 if (is_exported_allUnnamed() && !m->is_named()) {
42 return true;
43 } else if (!has_qual_exports_list()) {
44 return false;
45 } else {
46 return _qualified_exports->contains(m);
47 }
48 }
49
50 // Add a module to the package's qualified export list.
51 void PackageEntry::add_qexport(ModuleEntry* m) {
52 assert(Module_lock->owned_by_self(), "should have the Module_lock");
53 if (!has_qual_exports_list()) {
54 // Lazily create a package's qualified exports list.
55 // Initial size is small, do not anticipate export lists to be large.
170 // Walk through all buckets and all entries in each bucket,
171 // freeing each entry.
172 for (int i = 0; i < table_size(); ++i) {
173 for (PackageEntry* p = bucket(i); p != NULL;) {
174 PackageEntry* to_remove = p;
175 // read next before freeing.
176 p = p->next();
177
178 // Clean out the C heap allocated qualified exports list first before freeing the entry
179 to_remove->delete_qualified_exports();
180 to_remove->name()->decrement_refcount();
181
182 // Unlink from the Hashtable prior to freeing
183 unlink_entry(to_remove);
184 FREE_C_HEAP_ARRAY(char, to_remove);
185 }
186 }
187 assert(number_of_entries() == 0, "should have removed all entries");
188 assert(new_entry_free_list() == NULL, "entry present on PackageEntryTable's free list");
189 }
190
191 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
192 assert(Module_lock->owned_by_self(), "should have the Module_lock");
193 PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
194
195 JFR_ONLY(INIT_ID(entry);)
196
197 // Initialize fields specific to a PackageEntry
198 entry->init();
199 entry->name()->increment_refcount();
200 entry->set_module(module);
201 return entry;
202 }
203
204 void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) {
205 assert(Module_lock->owned_by_self(), "should have the Module_lock");
206 Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
207 }
208
209 // Create package entry in loader's package entry table. Assume Module lock
|
1 /*
2 * Copyright (c) 2016, 2020, 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 #include "precompiled.hpp"
26 #include "classfile/moduleEntry.hpp"
27 #include "classfile/packageEntry.hpp"
28 #include "logging/log.hpp"
29 #include "memory/archiveUtils.hpp"
30 #include "memory/metaspaceShared.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/array.hpp"
33 #include "oops/symbol.hpp"
34 #include "runtime/handles.inline.hpp"
35 #include "utilities/events.hpp"
36 #include "utilities/growableArray.hpp"
37 #include "utilities/hashtable.inline.hpp"
38 #include "utilities/ostream.hpp"
39 #include "utilities/resourceHash.hpp"
40
41 // Returns true if this package specifies m as a qualified export, including through an unnamed export
42 bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
43 assert(Module_lock->owned_by_self(), "should have the Module_lock");
44 assert(m != NULL, "No module to lookup in this package's qualified exports list");
45 if (is_exported_allUnnamed() && !m->is_named()) {
46 return true;
47 } else if (!has_qual_exports_list()) {
48 return false;
49 } else {
50 return _qualified_exports->contains(m);
51 }
52 }
53
54 // Add a module to the package's qualified export list.
55 void PackageEntry::add_qexport(ModuleEntry* m) {
56 assert(Module_lock->owned_by_self(), "should have the Module_lock");
57 if (!has_qual_exports_list()) {
58 // Lazily create a package's qualified exports list.
59 // Initial size is small, do not anticipate export lists to be large.
174 // Walk through all buckets and all entries in each bucket,
175 // freeing each entry.
176 for (int i = 0; i < table_size(); ++i) {
177 for (PackageEntry* p = bucket(i); p != NULL;) {
178 PackageEntry* to_remove = p;
179 // read next before freeing.
180 p = p->next();
181
182 // Clean out the C heap allocated qualified exports list first before freeing the entry
183 to_remove->delete_qualified_exports();
184 to_remove->name()->decrement_refcount();
185
186 // Unlink from the Hashtable prior to freeing
187 unlink_entry(to_remove);
188 FREE_C_HEAP_ARRAY(char, to_remove);
189 }
190 }
191 assert(number_of_entries() == 0, "should have removed all entries");
192 assert(new_entry_free_list() == NULL, "entry present on PackageEntryTable's free list");
193 }
194
195 #if INCLUDE_CDS_JAVA_HEAP
196 typedef ResourceHashtable<
197 const PackageEntry*,
198 PackageEntry*,
199 primitive_hash<const PackageEntry*>,
200 primitive_equals<const PackageEntry*>,
201 557, // prime number
202 ResourceObj::C_HEAP> ArchivedPackageEntries;
203 static ArchivedPackageEntries* _archived_packages_entries = NULL;
204
205 PackageEntry* PackageEntry::allocate_archived_entry() const {
206 assert(!in_unnamed_module(), "unnamed packages/modules are not archived");
207 PackageEntry* archived_entry = (PackageEntry*)MetaspaceShared::read_write_space_alloc(sizeof(PackageEntry));
208 memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry));
209
210 if (_archived_packages_entries == NULL) {
211 _archived_packages_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedPackageEntries();
212 }
213 assert(_archived_packages_entries->get(this) == NULL, "Each PackageEntry must not be shared across PackageEntryTables");
214 _archived_packages_entries->put(this, archived_entry);
215
216 return archived_entry;
217 }
218
219 PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) {
220 PackageEntry** ptr = _archived_packages_entries->get(orig_entry);
221 assert(ptr != NULL && *ptr != NULL, "must have been allocated");
222 return *ptr;
223 }
224
225 void PackageEntry::init_as_archived_entry() {
226 Array<ModuleEntry*>* archived_qualified_exports = ModuleEntry::write_archived_entry_array(_qualified_exports);
227
228 set_next(NULL);
229 set_literal(MetaspaceShared::get_relocated_symbol(literal()));
230 set_hash(0x0); // re-init at runtime
231 _module = ModuleEntry::get_archived_entry(_module);
232 _qualified_exports = (GrowableArray<ModuleEntry*>*)archived_qualified_exports;
233 _defined_by_cds_in_class_path = 0;
234
235 ArchivePtrMarker::mark_pointer((address*)literal_addr());
236 ArchivePtrMarker::mark_pointer((address*)&_module);
237 ArchivePtrMarker::mark_pointer((address*)&_qualified_exports);
238 }
239
240 void PackageEntry::load_from_archive() {
241 _qualified_exports = ModuleEntry::read_archived_entry_array((Array<ModuleEntry*>*)_qualified_exports);
242 JFR_ONLY(INIT_ID(this);)
243 }
244
245 static int compare_package_by_name(PackageEntry** a, PackageEntry** b) {
246 return a[0]->name()->fast_compare(b[0]->name());
247 }
248
249 Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() {
250 // First count the packages in named modules
251 int n, i;
252 for (n = 0, i = 0; i < table_size(); ++i) {
253 for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
254 if (p->module()->name() != NULL) {
255 n++;
256 }
257 }
258 }
259
260 Array<PackageEntry*>* archived_packages = MetaspaceShared::new_rw_array<PackageEntry*>(n);
261 for (n = 0, i = 0; i < table_size(); ++i) {
262 for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
263 if (p->module()->name() != NULL) {
264 // We don't archive unnamed modules, or packages in unnamed modules. They will be
265 // created on-demand at runtime as classes in such packages are loaded.
266 archived_packages->at_put(n++, p);
267 }
268 }
269 }
270 if (n > 0) {
271 qsort(archived_packages->adr_at(0), n, sizeof(PackageEntry*), (_sort_Fn)compare_package_by_name);
272 for (i = 0; i < n; i++) {
273 archived_packages->at_put(i, archived_packages->at(i)->allocate_archived_entry());
274 ArchivePtrMarker::mark_pointer((address*)archived_packages->adr_at(i));
275 }
276 }
277 return archived_packages;
278 }
279
280 void PackageEntryTable::init_archived_entries(Array<PackageEntry*>* archived_packages) {
281 for (int i = 0; i < archived_packages->length(); i++) {
282 PackageEntry* archived_entry = archived_packages->at(i);
283 archived_entry->init_as_archived_entry();
284 }
285 }
286
287 void PackageEntryTable::load_archived_entries(Array<PackageEntry*>* archived_packages) {
288 assert(UseSharedSpaces, "runtime only");
289
290 MutexLocker m1(Module_lock);
291 for (int i = 0; i < archived_packages->length(); i++) {
292 PackageEntry* archived_entry = archived_packages->at(i);
293 archived_entry->load_from_archive();
294
295 unsigned int hash = compute_hash(archived_entry->name());
296 archived_entry->set_hash(hash);
297 add_entry(hash_to_index(hash), archived_entry);
298 }
299 }
300
301 #endif
302
303 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
304 assert(Module_lock->owned_by_self(), "should have the Module_lock");
305 PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
306
307 JFR_ONLY(INIT_ID(entry);)
308
309 // Initialize fields specific to a PackageEntry
310 entry->init();
311 entry->name()->increment_refcount();
312 entry->set_module(module);
313 return entry;
314 }
315
316 void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) {
317 assert(Module_lock->owned_by_self(), "should have the Module_lock");
318 Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
319 }
320
321 // Create package entry in loader's package entry table. Assume Module lock
|