jdk

Форк
0
/
classLoaderDataShared.cpp 
208 строк · 8.3 Кб
1
 /*
2
 * Copyright (c) 2020, 2024, 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 "cds/cdsConfig.hpp"
27
#include "cds/serializeClosure.hpp"
28
#include "classfile/classLoaderData.inline.hpp"
29
#include "classfile/classLoaderDataShared.hpp"
30
#include "classfile/moduleEntry.hpp"
31
#include "classfile/packageEntry.hpp"
32
#include "classfile/systemDictionary.hpp"
33
#include "logging/log.hpp"
34
#include "runtime/handles.inline.hpp"
35

36
#if INCLUDE_CDS_JAVA_HEAP
37

38
bool ClassLoaderDataShared::_full_module_graph_loaded = false;
39

40
class ArchivedClassLoaderData {
41
  Array<PackageEntry*>* _packages;
42
  Array<ModuleEntry*>* _modules;
43

44
  void assert_valid(ClassLoaderData* loader_data) {
45
    // loader_data may be null if the boot layer has loaded no modules for the platform or
46
    // system loaders (e.g., if you create a custom JDK image with only java.base).
47
    if (loader_data != nullptr) {
48
      assert(!loader_data->has_class_mirror_holder(),
49
             "loaders for non-strong hidden classes not supported");
50
    }
51
  }
52
public:
53
  ArchivedClassLoaderData() : _packages(nullptr), _modules(nullptr) {}
54

55
  void iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure);
56
  void allocate(ClassLoaderData* loader_data);
57
  void init_archived_entries(ClassLoaderData* loader_data);
58

59
  void serialize(SerializeClosure* f) {
60
    f->do_ptr(&_packages);
61
    f->do_ptr(&_modules);
62
  }
63

64
  void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops);
65
  void clear_archived_oops();
66
};
67

68
static ArchivedClassLoaderData _archived_boot_loader_data;
69
static ArchivedClassLoaderData _archived_platform_loader_data;
70
static ArchivedClassLoaderData _archived_system_loader_data;
71
static ModuleEntry* _archived_javabase_moduleEntry = nullptr;
72

73
void ArchivedClassLoaderData::iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure) {
74
  assert(CDSConfig::is_dumping_full_module_graph(), "must be");
75
  assert_valid(loader_data);
76
  if (loader_data != nullptr) {
77
    loader_data->packages()->iterate_symbols(closure);
78
    loader_data->modules() ->iterate_symbols(closure);
79
  }
80
}
81

82
void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) {
83
  assert(CDSConfig::is_dumping_full_module_graph(), "must be");
84
  assert_valid(loader_data);
85
  if (loader_data != nullptr) {
86
    // We can't create hashtables at dump time because the hashcode depends on the
87
    // address of the Symbols, which may be relocated at runtime due to ASLR.
88
    // So we store the packages/modules in Arrays. At runtime, we create
89
    // the hashtables using these arrays.
90
    _packages = loader_data->packages()->allocate_archived_entries();
91
    _modules  = loader_data->modules() ->allocate_archived_entries();
92
  }
93
}
94

95
void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data) {
96
  assert(CDSConfig::is_dumping_full_module_graph(), "must be");
97
  assert_valid(loader_data);
98
  if (loader_data != nullptr) {
99
    loader_data->packages()->init_archived_entries(_packages);
100
    loader_data->modules() ->init_archived_entries(_modules);
101
  }
102
}
103

104
void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops) {
105
  assert(CDSConfig::is_using_archive(), "must be");
106
  assert_valid(loader_data);
107
  if (_modules != nullptr) { // Could be null if we have archived no modules for platform/system loaders
108
    ModuleEntryTable* modules = loader_data->modules();
109
    PackageEntryTable* packages = loader_data->packages();
110

111
    MutexLocker m1(Module_lock);
112
    if (do_entries) {
113
      modules->load_archived_entries(loader_data, _modules);
114
      packages->load_archived_entries(_packages);
115
    }
116
    if (do_oops) {
117
      modules->restore_archived_oops(loader_data, _modules);
118
    }
119
  }
120
}
121

122
void ArchivedClassLoaderData::clear_archived_oops() {
123
  assert(CDSConfig::is_using_archive(), "must be");
124
  if (_modules != nullptr) {
125
    for (int i = 0; i < _modules->length(); i++) {
126
      _modules->at(i)->clear_archived_oops();
127
    }
128
  }
129
}
130

131
// ------------------------------
132

133
static ClassLoaderData* null_class_loader_data() {
134
  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
135
  assert(loader_data != nullptr, "must be");
136
  return loader_data;
137
}
138

139
static ClassLoaderData* java_platform_loader_data_or_null() {
140
  return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader());
141
}
142

143
static ClassLoaderData* java_system_loader_data_or_null() {
144
  return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader());
145
}
146

147
void ClassLoaderDataShared::iterate_symbols(MetaspaceClosure* closure) {
148
  assert(CDSConfig::is_dumping_full_module_graph(), "must be");
149
  _archived_boot_loader_data.iterate_symbols    (null_class_loader_data(), closure);
150
  _archived_platform_loader_data.iterate_symbols(java_platform_loader_data_or_null(), closure);
151
  _archived_system_loader_data.iterate_symbols  (java_system_loader_data_or_null(), closure);
152
}
153

154
void ClassLoaderDataShared::allocate_archived_tables() {
155
  assert(CDSConfig::is_dumping_full_module_graph(), "must be");
156
  _archived_boot_loader_data.allocate    (null_class_loader_data());
157
  _archived_platform_loader_data.allocate(java_platform_loader_data_or_null());
158
  _archived_system_loader_data.allocate  (java_system_loader_data_or_null());
159
}
160

161
void ClassLoaderDataShared::init_archived_tables() {
162
  assert(CDSConfig::is_dumping_full_module_graph(), "must be");
163
  _archived_boot_loader_data.init_archived_entries    (null_class_loader_data());
164
  _archived_platform_loader_data.init_archived_entries(java_platform_loader_data_or_null());
165
  _archived_system_loader_data.init_archived_entries  (java_system_loader_data_or_null());
166
  _archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry());
167
}
168

169
void ClassLoaderDataShared::serialize(SerializeClosure* f) {
170
  _archived_boot_loader_data.serialize(f);
171
  _archived_platform_loader_data.serialize(f);
172
  _archived_system_loader_data.serialize(f);
173
  f->do_ptr(&_archived_javabase_moduleEntry);
174

175
  if (f->reading() && CDSConfig::is_using_full_module_graph()) {
176
    // Must be done before ClassLoader::create_javabase()
177
    _archived_boot_loader_data.restore(null_class_loader_data(), true, false);
178
    ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
179
    log_info(cds)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
180
                  p2i(_archived_javabase_moduleEntry));
181
  }
182
}
183

184
void ClassLoaderDataShared::clear_archived_oops() {
185
  assert(!CDSConfig::is_using_full_module_graph(), "must be");
186
  _archived_boot_loader_data.clear_archived_oops();
187
  _archived_platform_loader_data.clear_archived_oops();
188
  _archived_system_loader_data.clear_archived_oops();
189
}
190

191
oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() {
192
  assert(CDSConfig::is_using_full_module_graph(), "must be");
193
  _archived_boot_loader_data.restore(null_class_loader_data(), false, true);
194
  return _archived_javabase_moduleEntry->module();
195
}
196

197
void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoaderData* loader_data) {
198
  assert(CDSConfig::is_using_full_module_graph(), "must be");
199
  _archived_platform_loader_data.restore(loader_data, true, true);
200
}
201

202
void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) {
203
  assert(CDSConfig::is_using_full_module_graph(), "must be");
204
  _archived_system_loader_data.restore(loader_data, true, true);
205
  _full_module_graph_loaded = true;
206
}
207

208
#endif // INCLUDE_CDS_JAVA_HEAP
209

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.