Skip to content

Commit b50eb99

Browse files
committed
Merge branch 'master' into 8248186-refactor-cds-cpp-vtables
2 parents b1db967 + 03a4df0 commit b50eb99

File tree

72 files changed

+2167
-220
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2167
-220
lines changed

make/hotspot/lib/JvmFeatures.gmk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ ifneq ($(call check-jvm-feature, cds), true)
119119
archiveBuilder.cpp \
120120
archiveUtils.cpp \
121121
classListParser.cpp \
122+
classLoaderDataShared.cpp \
122123
classLoaderExt.cpp \
123124
cppVtables.cpp \
124125
dumpAllocStats.cpp \

make/hotspot/symbols/symbols-unix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,5 +198,6 @@ JVM_AddModuleExports
198198
JVM_AddModuleExportsToAll
199199
JVM_AddModuleExportsToAllUnnamed
200200
JVM_AddReadsModule
201+
JVM_DefineArchivedModules
201202
JVM_DefineModule
202203
JVM_SetBootLoaderUnnamedModule

src/hotspot/share/classfile/classLoader.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1644,12 +1644,14 @@ void ClassLoader::create_javabase() {
16441644

16451645
{
16461646
MutexLocker ml(THREAD, Module_lock);
1647-
ModuleEntry* jb_module = null_cld_modules->locked_create_entry(Handle(),
1647+
if (ModuleEntryTable::javabase_moduleEntry() == NULL) { // may have been inited by CDS.
1648+
ModuleEntry* jb_module = null_cld_modules->locked_create_entry(Handle(),
16481649
false, vmSymbols::java_base(), NULL, NULL, null_cld);
1649-
if (jb_module == NULL) {
1650-
vm_exit_during_initialization("Unable to create ModuleEntry for " JAVA_BASE_NAME);
1650+
if (jb_module == NULL) {
1651+
vm_exit_during_initialization("Unable to create ModuleEntry for " JAVA_BASE_NAME);
1652+
}
1653+
ModuleEntryTable::set_javabase_moduleEntry(jb_module);
16511654
}
1652-
ModuleEntryTable::set_javabase_moduleEntry(jb_module);
16531655
}
16541656
}
16551657

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*
2+
* Copyright (c) 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/classLoaderData.inline.hpp"
27+
#include "classfile/classLoaderDataShared.hpp"
28+
#include "classfile/moduleEntry.hpp"
29+
#include "classfile/packageEntry.hpp"
30+
#include "logging/log.hpp"
31+
#include "memory/metaspaceShared.hpp"
32+
#include "runtime/handles.inline.hpp"
33+
34+
#if INCLUDE_CDS_JAVA_HEAP
35+
36+
class ArchivedClassLoaderData {
37+
Array<PackageEntry*>* _packages;
38+
Array<ModuleEntry*>* _modules;
39+
40+
void assert_valid(ClassLoaderData* loader_data) {
41+
// loader_data may be NULL if the boot layer has loaded no modules for the platform or
42+
// system loaders (e.g., if you create a custom JDK image with only java.base).
43+
if (loader_data != NULL) {
44+
assert(!loader_data->has_class_mirror_holder(),
45+
"loaders for non-strong hidden classes or unsafe anonymous classes not supported");
46+
}
47+
}
48+
public:
49+
ArchivedClassLoaderData() : _packages(NULL), _modules(NULL) {}
50+
51+
void iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure);
52+
void allocate(ClassLoaderData* loader_data);
53+
void init_archived_entries(ClassLoaderData* loader_data);
54+
void init_archived_oops(ClassLoaderData* loader_data);
55+
56+
void serialize(SerializeClosure* f) {
57+
f->do_ptr((void**)&_packages);
58+
f->do_ptr((void**)&_modules);
59+
}
60+
61+
void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops);
62+
};
63+
64+
static ArchivedClassLoaderData _archived_boot_loader_data;
65+
static ArchivedClassLoaderData _archived_platform_loader_data;
66+
static ArchivedClassLoaderData _archived_system_loader_data;
67+
static ModuleEntry* _archived_javabase_moduleEntry = NULL;
68+
69+
void ArchivedClassLoaderData::iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure) {
70+
assert(DumpSharedSpaces, "must be");
71+
assert_valid(loader_data);
72+
if (loader_data != NULL) {
73+
loader_data->packages()->iterate_symbols(closure);
74+
loader_data->modules() ->iterate_symbols(closure);
75+
}
76+
}
77+
78+
void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) {
79+
assert(DumpSharedSpaces, "must be");
80+
assert_valid(loader_data);
81+
if (loader_data != NULL) {
82+
// We can't create hashtables at dump time because the hashcode depends on the
83+
// address of the Symbols, which may be relocated at runtime due to ASLR.
84+
// So we store the packages/modules in Arrays. At runtime, we create
85+
// the hashtables using these arrays.
86+
_packages = loader_data->packages()->allocate_archived_entries();
87+
_modules = loader_data->modules() ->allocate_archived_entries();
88+
}
89+
}
90+
91+
void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data) {
92+
assert(DumpSharedSpaces, "must be");
93+
assert_valid(loader_data);
94+
if (loader_data != NULL) {
95+
loader_data->packages()->init_archived_entries(_packages);
96+
loader_data->modules() ->init_archived_entries(_modules);
97+
}
98+
}
99+
100+
void ArchivedClassLoaderData::init_archived_oops(ClassLoaderData* loader_data) {
101+
assert(DumpSharedSpaces, "must be");
102+
assert_valid(loader_data);
103+
if (loader_data != NULL) {
104+
loader_data->modules()->init_archived_oops(_modules);
105+
}
106+
}
107+
108+
void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops) {
109+
assert(UseSharedSpaces, "must be");
110+
assert_valid(loader_data);
111+
if (_modules != NULL) { // Could be NULL if we have archived no modules for platform/system loaders
112+
ModuleEntryTable* modules = loader_data->modules();
113+
PackageEntryTable* packages = loader_data->packages();
114+
115+
MutexLocker m1(Module_lock);
116+
if (do_entries) {
117+
modules->load_archived_entries(loader_data, _modules);
118+
packages->load_archived_entries(_packages);
119+
}
120+
if (do_oops) {
121+
modules->restore_archived_oops(loader_data, _modules);
122+
}
123+
}
124+
}
125+
126+
// ------------------------------
127+
128+
static ClassLoaderData* null_class_loader_data() {
129+
ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
130+
assert(loader_data != NULL, "must be");
131+
return loader_data;
132+
}
133+
134+
static ClassLoaderData* java_platform_loader_data_or_null() {
135+
return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader());
136+
}
137+
138+
static ClassLoaderData* java_system_loader_data_or_null() {
139+
return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader());
140+
}
141+
142+
void ClassLoaderDataShared::iterate_symbols(MetaspaceClosure* closure) {
143+
assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
144+
_archived_boot_loader_data.iterate_symbols (null_class_loader_data(), closure);
145+
_archived_platform_loader_data.iterate_symbols(java_platform_loader_data_or_null(), closure);
146+
_archived_system_loader_data.iterate_symbols (java_system_loader_data_or_null(), closure);
147+
}
148+
149+
void ClassLoaderDataShared::allocate_archived_tables() {
150+
assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
151+
_archived_boot_loader_data.allocate (null_class_loader_data());
152+
_archived_platform_loader_data.allocate(java_platform_loader_data_or_null());
153+
_archived_system_loader_data.allocate (java_system_loader_data_or_null());
154+
}
155+
156+
void ClassLoaderDataShared::init_archived_tables() {
157+
assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
158+
_archived_boot_loader_data.init_archived_entries (null_class_loader_data());
159+
_archived_platform_loader_data.init_archived_entries(java_platform_loader_data_or_null());
160+
_archived_system_loader_data.init_archived_entries (java_system_loader_data_or_null());
161+
_archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry());
162+
}
163+
164+
void ClassLoaderDataShared::init_archived_oops() {
165+
assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
166+
_archived_boot_loader_data.init_archived_oops (null_class_loader_data());
167+
_archived_platform_loader_data.init_archived_oops(java_platform_loader_data_or_null());
168+
_archived_system_loader_data.init_archived_oops (java_system_loader_data_or_null());
169+
}
170+
171+
void ClassLoaderDataShared::serialize(SerializeClosure* f) {
172+
_archived_boot_loader_data.serialize(f);
173+
_archived_platform_loader_data.serialize(f);
174+
_archived_system_loader_data.serialize(f);
175+
f->do_ptr((void**)&_archived_javabase_moduleEntry);
176+
177+
if (f->reading() && MetaspaceShared::use_full_module_graph()) {
178+
// Must be done before ClassLoader::create_javabase()
179+
_archived_boot_loader_data.restore(null_class_loader_data(), true, false);
180+
ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
181+
log_info(cds)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
182+
p2i(_archived_javabase_moduleEntry));
183+
}
184+
}
185+
186+
oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() {
187+
assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
188+
_archived_boot_loader_data.restore(null_class_loader_data(), false, true);
189+
return _archived_javabase_moduleEntry->module();
190+
}
191+
192+
void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoaderData* loader_data) {
193+
assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
194+
_archived_platform_loader_data.restore(loader_data, true, true);
195+
}
196+
197+
void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) {
198+
assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
199+
_archived_system_loader_data.restore(loader_data, true, true);
200+
}
201+
202+
#endif // INCLUDE_CDS_JAVA_HEAP
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 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+
#ifndef SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP
26+
#define SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP
27+
28+
#include "memory/allStatic.hpp"
29+
#include "oops/oopsHierarchy.hpp"
30+
31+
class ClassLoaderData;
32+
class MetaspaceClosure;
33+
class SerializeClosure;
34+
35+
class ClassLoaderDataShared : AllStatic {
36+
public:
37+
static void allocate_archived_tables();
38+
static void iterate_symbols(MetaspaceClosure* closure);
39+
static void init_archived_tables();
40+
static void init_archived_oops();
41+
static void serialize(SerializeClosure* f);
42+
static oop restore_archived_oops_for_null_class_loader_data();
43+
static void restore_java_platform_loader_from_archive(ClassLoaderData* loader_data);
44+
static void restore_java_system_loader_from_archive(ClassLoaderData* loader_data);
45+
};
46+
47+
#endif // SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP

src/hotspot/share/classfile/javaClasses.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3392,12 +3392,17 @@ void java_lang_Module::set_name(oop module, oop value) {
33923392
module->obj_field_put(_name_offset, value);
33933393
}
33943394

3395-
ModuleEntry* java_lang_Module::module_entry(oop module) {
3395+
ModuleEntry* java_lang_Module::module_entry_raw(oop module) {
33963396
assert(_module_entry_offset != 0, "Uninitialized module_entry_offset");
33973397
assert(module != NULL, "module can't be null");
33983398
assert(oopDesc::is_oop(module), "module must be oop");
33993399

34003400
ModuleEntry* module_entry = (ModuleEntry*)module->address_field(_module_entry_offset);
3401+
return module_entry;
3402+
}
3403+
3404+
ModuleEntry* java_lang_Module::module_entry(oop module) {
3405+
ModuleEntry* module_entry = module_entry_raw(module);
34013406
if (module_entry == NULL) {
34023407
// If the inject field containing the ModuleEntry* is null then return the
34033408
// class loader's unnamed module.
@@ -4821,9 +4826,8 @@ bool JavaClasses::is_supported_for_archiving(oop obj) {
48214826
Klass* klass = obj->klass();
48224827

48234828
if (klass == SystemDictionary::ClassLoader_klass() || // ClassLoader::loader_data is malloc'ed.
4824-
klass == SystemDictionary::Module_klass() || // Module::module_entry is malloc'ed
48254829
// The next 3 classes are used to implement java.lang.invoke, and are not used directly in
4826-
// regular Java code. The implementation of java.lang.invoke uses generated anonymoys classes
4830+
// regular Java code. The implementation of java.lang.invoke uses generated anonymous classes
48274831
// (e.g., as referenced by ResolvedMethodName::vmholder) that are not yet supported by CDS.
48284832
// So for now we cannot not support these classes for archiving.
48294833
//

src/hotspot/share/classfile/javaClasses.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ class java_lang_Module {
797797
static void set_name(oop module, oop value);
798798

799799
static ModuleEntry* module_entry(oop module);
800+
static ModuleEntry* module_entry_raw(oop module);
800801
static void set_module_entry(oop module, ModuleEntry* module_entry);
801802

802803
friend class JavaClasses;

0 commit comments

Comments
 (0)