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