1 /*
2 * Copyright (c) 2021, 2023, 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 *
25 #ifndef SHARE_CDS_DUMPTIMECLASSINFO_HPP
26 #define SHARE_CDS_DUMPTIMECLASSINFO_HPP
27
28 #include "cds/archiveBuilder.hpp"
29 #include "cds/archiveUtils.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/metaspaceShared.hpp"
32 #include "classfile/compactHashtable.hpp"
33 #include "memory/metaspaceClosure.hpp"
34 #include "oops/instanceKlass.hpp"
35 #include "prims/jvmtiExport.hpp"
36 #include "utilities/growableArray.hpp"
37
38 class Method;
39 class Symbol;
40
41 class DumpTimeClassInfo: public CHeapObj<mtClass> {
42 bool _excluded;
43 bool _is_early_klass;
44 bool _has_checked_exclusion;
45
46 class DTLoaderConstraint {
47 Symbol* _name;
48 char _loader_type1;
49 char _loader_type2;
50 public:
51 DTLoaderConstraint() : _name(nullptr), _loader_type1('0'), _loader_type2('0') {}
52 DTLoaderConstraint(Symbol* name, char l1, char l2) : _name(name), _loader_type1(l1), _loader_type2(l2) {
53 Symbol::maybe_increment_refcount(_name);
54 }
55 DTLoaderConstraint(const DTLoaderConstraint& src) {
56 _name = src._name;
57 _loader_type1 = src._loader_type1;
58 _loader_type2 = src._loader_type2;
59 Symbol::maybe_increment_refcount(_name);
60 }
61 DTLoaderConstraint& operator=(DTLoaderConstraint src) {
62 swap(_name, src._name); // c++ copy-and-swap idiom
63 _loader_type1 = src._loader_type1;
64 _loader_type2 = src._loader_type2;
65 return *this;
120
121 public:
122 InstanceKlass* _klass;
123 InstanceKlass* _nest_host;
124 bool _failed_verification;
125 bool _is_archived_lambda_proxy;
126 int _id;
127 int _clsfile_size;
128 int _clsfile_crc32;
129 GrowableArray<DTVerifierConstraint>* _verifier_constraints;
130 GrowableArray<char>* _verifier_constraint_flags;
131 GrowableArray<DTLoaderConstraint>* _loader_constraints;
132 GrowableArray<int>* _enum_klass_static_fields;
133
134 DumpTimeClassInfo() {
135 _klass = nullptr;
136 _nest_host = nullptr;
137 _failed_verification = false;
138 _is_archived_lambda_proxy = false;
139 _has_checked_exclusion = false;
140 _id = -1;
141 _clsfile_size = -1;
142 _clsfile_crc32 = -1;
143 _excluded = false;
144 _is_early_klass = JvmtiExport::is_early_phase();
145 _verifier_constraints = nullptr;
146 _verifier_constraint_flags = nullptr;
147 _loader_constraints = nullptr;
148 _enum_klass_static_fields = nullptr;
149 }
150 DumpTimeClassInfo& operator=(const DumpTimeClassInfo&) = delete;
151 ~DumpTimeClassInfo();
152
153 void add_verification_constraint(InstanceKlass* k, Symbol* name,
154 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object);
155 void record_linking_constraint(Symbol* name, Handle loader1, Handle loader2);
156 void add_enum_klass_static_field(int archived_heap_root_index);
157 int enum_klass_static_field(int which_field);
158 bool is_builtin();
159
179
180 int num_enum_klass_static_fields() const {
181 return array_length_or_zero(_enum_klass_static_fields);
182 }
183
184 void metaspace_pointers_do(MetaspaceClosure* it) {
185 it->push(&_klass);
186 it->push(&_nest_host);
187 if (_verifier_constraints != nullptr) {
188 for (int i = 0; i < _verifier_constraints->length(); i++) {
189 _verifier_constraints->adr_at(i)->metaspace_pointers_do(it);
190 }
191 }
192 if (_loader_constraints != nullptr) {
193 for (int i = 0; i < _loader_constraints->length(); i++) {
194 _loader_constraints->adr_at(i)->metaspace_pointers_do(it);
195 }
196 }
197 }
198
199 bool is_excluded() {
200 return _excluded || _failed_verification;
201 }
202
203 // Was this class loaded while JvmtiExport::is_early_phase()==true
204 bool is_early_klass() {
205 return _is_early_klass;
206 }
207
208 // simple accessors
209 void set_excluded() { _excluded = true; }
210 bool has_checked_exclusion() const { return _has_checked_exclusion; }
211 void set_has_checked_exclusion() { _has_checked_exclusion = true; }
212 bool failed_verification() const { return _failed_verification; }
213 void set_failed_verification() { _failed_verification = true; }
214 InstanceKlass* nest_host() const { return _nest_host; }
215 void set_nest_host(InstanceKlass* nest_host) { _nest_host = nest_host; }
216
217 size_t runtime_info_bytesize() const;
218 };
219
220 template <typename T>
221 inline unsigned DumpTimeSharedClassTable_hash(T* const& k) {
222 if (CDSConfig::is_dumping_static_archive()) {
223 // Deterministic archive contents
224 uintx delta = k->name() - MetaspaceShared::symbol_rs_base();
225 return primitive_hash<uintx>(delta);
226 } else {
227 // Deterministic archive is not possible because classes can be loaded
228 // in multiple threads.
229 return primitive_hash<T*>(k);
230 }
231 }
232
233 using DumpTimeSharedClassTableBaseType = ResourceHashtable<
234 InstanceKlass*,
235 DumpTimeClassInfo,
236 15889, // prime number
245 public:
246 DumpTimeSharedClassTable() {
247 _builtin_count = 0;
248 _unregistered_count = 0;
249 }
250 DumpTimeClassInfo* allocate_info(InstanceKlass* k);
251 DumpTimeClassInfo* get_info(InstanceKlass* k);
252 void inc_builtin_count() { _builtin_count++; }
253 void inc_unregistered_count() { _unregistered_count++; }
254 void update_counts();
255 int count_of(bool is_builtin) const {
256 if (is_builtin) {
257 return _builtin_count;
258 } else {
259 return _unregistered_count;
260 }
261 }
262
263 template<class ITER> void iterate_all_live_classes(ITER* iter) const;
264 template<typename Function> void iterate_all_live_classes(Function function) const;
265
266 private:
267 // It's unsafe to iterate on classes whose loader is dead.
268 // Declare these private and don't implement them. This forces users of
269 // DumpTimeSharedClassTable to use the iterate_all_live_classes() methods
270 // instead.
271 template<class ITER> void iterate(ITER* iter) const;
272 template<typename Function> void iterate(Function function) const;
273 template<typename Function> void iterate_all(Function function) const;
274 };
275
276 #endif // SHARE_CDS_DUMPTIMECLASSINFO_HPP
|
1 /*
2 * Copyright (c) 2021, 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 *
25 #ifndef SHARE_CDS_DUMPTIMECLASSINFO_HPP
26 #define SHARE_CDS_DUMPTIMECLASSINFO_HPP
27
28 #include "cds/archiveBuilder.hpp"
29 #include "cds/archiveUtils.hpp"
30 #include "cds/cdsConfig.hpp"
31 #include "cds/metaspaceShared.hpp"
32 #include "classfile/compactHashtable.hpp"
33 #include "memory/metaspaceClosure.hpp"
34 #include "oops/instanceKlass.hpp"
35 #include "prims/jvmtiExport.hpp"
36 #include "utilities/growableArray.hpp"
37
38 class Method;
39 class Symbol;
40
41 class DumpTimeClassInfo: public CHeapObj<mtClass> {
42 bool _excluded;
43 bool _is_early_klass;
44 bool _has_checked_exclusion;
45 bool _can_be_preinited;
46 bool _has_done_preinit_check;
47 bool _is_required;
48 bool _has_scanned_constant_pool;
49 class DTLoaderConstraint {
50 Symbol* _name;
51 char _loader_type1;
52 char _loader_type2;
53 public:
54 DTLoaderConstraint() : _name(nullptr), _loader_type1('0'), _loader_type2('0') {}
55 DTLoaderConstraint(Symbol* name, char l1, char l2) : _name(name), _loader_type1(l1), _loader_type2(l2) {
56 Symbol::maybe_increment_refcount(_name);
57 }
58 DTLoaderConstraint(const DTLoaderConstraint& src) {
59 _name = src._name;
60 _loader_type1 = src._loader_type1;
61 _loader_type2 = src._loader_type2;
62 Symbol::maybe_increment_refcount(_name);
63 }
64 DTLoaderConstraint& operator=(DTLoaderConstraint src) {
65 swap(_name, src._name); // c++ copy-and-swap idiom
66 _loader_type1 = src._loader_type1;
67 _loader_type2 = src._loader_type2;
68 return *this;
123
124 public:
125 InstanceKlass* _klass;
126 InstanceKlass* _nest_host;
127 bool _failed_verification;
128 bool _is_archived_lambda_proxy;
129 int _id;
130 int _clsfile_size;
131 int _clsfile_crc32;
132 GrowableArray<DTVerifierConstraint>* _verifier_constraints;
133 GrowableArray<char>* _verifier_constraint_flags;
134 GrowableArray<DTLoaderConstraint>* _loader_constraints;
135 GrowableArray<int>* _enum_klass_static_fields;
136
137 DumpTimeClassInfo() {
138 _klass = nullptr;
139 _nest_host = nullptr;
140 _failed_verification = false;
141 _is_archived_lambda_proxy = false;
142 _has_checked_exclusion = false;
143 _can_be_preinited = false;
144 _has_done_preinit_check = false;
145 _is_required = false;
146 _has_scanned_constant_pool = false;
147 _id = -1;
148 _clsfile_size = -1;
149 _clsfile_crc32 = -1;
150 _excluded = false;
151 _is_early_klass = JvmtiExport::is_early_phase();
152 _verifier_constraints = nullptr;
153 _verifier_constraint_flags = nullptr;
154 _loader_constraints = nullptr;
155 _enum_klass_static_fields = nullptr;
156 }
157 DumpTimeClassInfo& operator=(const DumpTimeClassInfo&) = delete;
158 ~DumpTimeClassInfo();
159
160 void add_verification_constraint(InstanceKlass* k, Symbol* name,
161 Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object);
162 void record_linking_constraint(Symbol* name, Handle loader1, Handle loader2);
163 void add_enum_klass_static_field(int archived_heap_root_index);
164 int enum_klass_static_field(int which_field);
165 bool is_builtin();
166
186
187 int num_enum_klass_static_fields() const {
188 return array_length_or_zero(_enum_klass_static_fields);
189 }
190
191 void metaspace_pointers_do(MetaspaceClosure* it) {
192 it->push(&_klass);
193 it->push(&_nest_host);
194 if (_verifier_constraints != nullptr) {
195 for (int i = 0; i < _verifier_constraints->length(); i++) {
196 _verifier_constraints->adr_at(i)->metaspace_pointers_do(it);
197 }
198 }
199 if (_loader_constraints != nullptr) {
200 for (int i = 0; i < _loader_constraints->length(); i++) {
201 _loader_constraints->adr_at(i)->metaspace_pointers_do(it);
202 }
203 }
204 }
205
206 bool is_excluded();
207
208 // Was this class loaded while JvmtiExport::is_early_phase()==true
209 bool is_early_klass() {
210 return _is_early_klass;
211 }
212
213 // simple accessors
214 void set_excluded() { _excluded = true; }
215 bool has_checked_exclusion() const { return _has_checked_exclusion; }
216 void set_has_checked_exclusion() { _has_checked_exclusion = true; }
217 bool failed_verification() const { return _failed_verification; }
218 void set_failed_verification() { _failed_verification = true; }
219 InstanceKlass* nest_host() const { return _nest_host; }
220 void set_nest_host(InstanceKlass* nest_host) { _nest_host = nest_host; }
221
222 bool can_be_preinited() const { return _can_be_preinited; }
223 bool has_done_preinit_check() const { return _has_done_preinit_check; }
224 bool is_required() const { return _is_required; }
225 void set_is_required() { _is_required = true; }
226 bool has_scanned_constant_pool() const { return _has_scanned_constant_pool; }
227 void set_has_scanned_constant_pool() { _has_scanned_constant_pool = true; }
228
229 void set_can_be_preinited(bool v) {
230 _can_be_preinited = v;
231 _has_done_preinit_check = true;
232 }
233 void reset_preinit_check() {
234 _can_be_preinited = false;
235 _has_done_preinit_check = false;
236 }
237
238 size_t runtime_info_bytesize() const;
239 };
240
241 template <typename T>
242 inline unsigned DumpTimeSharedClassTable_hash(T* const& k) {
243 if (CDSConfig::is_dumping_static_archive()) {
244 // Deterministic archive contents
245 uintx delta = k->name() - MetaspaceShared::symbol_rs_base();
246 return primitive_hash<uintx>(delta);
247 } else {
248 // Deterministic archive is not possible because classes can be loaded
249 // in multiple threads.
250 return primitive_hash<T*>(k);
251 }
252 }
253
254 using DumpTimeSharedClassTableBaseType = ResourceHashtable<
255 InstanceKlass*,
256 DumpTimeClassInfo,
257 15889, // prime number
266 public:
267 DumpTimeSharedClassTable() {
268 _builtin_count = 0;
269 _unregistered_count = 0;
270 }
271 DumpTimeClassInfo* allocate_info(InstanceKlass* k);
272 DumpTimeClassInfo* get_info(InstanceKlass* k);
273 void inc_builtin_count() { _builtin_count++; }
274 void inc_unregistered_count() { _unregistered_count++; }
275 void update_counts();
276 int count_of(bool is_builtin) const {
277 if (is_builtin) {
278 return _builtin_count;
279 } else {
280 return _unregistered_count;
281 }
282 }
283
284 template<class ITER> void iterate_all_live_classes(ITER* iter) const;
285 template<typename Function> void iterate_all_live_classes(Function function) const;
286 template<typename Function> void iterate_all_classes_in_builtin_loaders(Function function) const;
287
288 private:
289 // It's unsafe to iterate on classes whose loader is dead.
290 // Declare these private and don't implement them. This forces users of
291 // DumpTimeSharedClassTable to use the iterate_all_live_classes() methods
292 // instead.
293 template<class ITER> void iterate(ITER* iter) const;
294 template<typename Function> void iterate(Function function) const;
295 template<typename Function> void iterate_all(Function function) const;
296 };
297
298 #endif // SHARE_CDS_DUMPTIMECLASSINFO_HPP
|