< prev index next >

src/hotspot/share/cds/dumpTimeClassInfo.hpp

Print this page

  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
< prev index next >