/*
* Copyright ( c ) 2021 , 2022 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*
*/
#ifndef SHARED_CDS_DUMPTIMESHAREDCLASSINFO_HPP
#define SHARED_CDS_DUMPTIMESHAREDCLASSINFO_HPP
#include "cds/archiveBuilder.hpp"
#include "cds/archiveUtils.hpp"
#include "cds/metaspaceShared.hpp"
#include "classfile/compactHashtable.hpp"
#include "memory/metaspaceClosure.hpp"
#include "oops/instanceKlass.hpp"
#include "prims/jvmtiExport.hpp"
#include "utilities/growableArray.hpp"
class Method;
class Symbol;
class DumpTimeClassInfo: public CHeapObj<mtClass> {
bool _excluded;
bool _is_early_klass;
bool _has_checked_exclusion;
class DTLoaderConstraint {
Symbol* _name;
char _loader_type1;
char _loader_type2;
public :
DTLoaderConstraint() : _name(NULL), _loader_type1('0' ), _loader_type2('0' ) {}
DTLoaderConstraint(Symbol* name, char l1, char l2) : _name(name), _loader_type1(l1), _loader_type2(l2) {
Symbol::maybe_increment_refcount(_name);
}
DTLoaderConstraint(const DTLoaderConstraint& src) {
_name = src._name;
_loader_type1 = src._loader_type1;
_loader_type2 = src._loader_type2;
Symbol::maybe_increment_refcount(_name);
}
DTLoaderConstraint& operator =(DTLoaderConstraint src) {
swap(_name, src._name); // c++ copy-and-swap idiom
_loader_type1 = src._loader_type1;
_loader_type2 = src._loader_type2;
return *this ;
}
~DTLoaderConstraint() {
Symbol::maybe_decrement_refcount(_name);
}
bool equals(const DTLoaderConstraint& t) {
return t._name == _name &&
((t._loader_type1 == _loader_type1 && t._loader_type2 == _loader_type2) ||
(t._loader_type2 == _loader_type1 && t._loader_type1 == _loader_type2));
}
void metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_name);
}
Symbol* name() { return _name; }
char loader_type1() { return _loader_type1; }
char loader_type2() { return _loader_type2; }
};
class DTVerifierConstraint {
Symbol* _name;
Symbol* _from_name;
public :
DTVerifierConstraint() : _name(NULL), _from_name(NULL) {}
DTVerifierConstraint(Symbol* n, Symbol* fn) : _name(n), _from_name(fn) {
Symbol::maybe_increment_refcount(_name);
Symbol::maybe_increment_refcount(_from_name);
}
DTVerifierConstraint(const DTVerifierConstraint& src) {
_name = src._name;
_from_name = src._from_name;
Symbol::maybe_increment_refcount(_name);
Symbol::maybe_increment_refcount(_from_name);
}
DTVerifierConstraint& operator =(DTVerifierConstraint src) {
swap(_name, src._name); // c++ copy-and-swap idiom
swap(_from_name, src._from_name); // c++ copy-and-swap idiom
return *this ;
}
~DTVerifierConstraint() {
Symbol::maybe_decrement_refcount(_name);
Symbol::maybe_decrement_refcount(_from_name);
}
bool equals(Symbol* n, Symbol* fn) {
return (_name == n) && (_from_name == fn);
}
void metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_name);
it->push(&_from_name);
}
Symbol* name() { return _name; }
Symbol* from_name() { return _from_name; }
};
public :
InstanceKlass* _klass;
InstanceKlass* _nest_host;
bool _failed_verification;
bool _is_archived_lambda_proxy;
int _id;
int _clsfile_size;
int _clsfile_crc32;
GrowableArray<DTVerifierConstraint>* _verifier_constraints;
GrowableArray<char>* _verifier_constraint_flags;
GrowableArray<DTLoaderConstraint>* _loader_constraints;
GrowableArray<int>* _enum_klass_static_fields;
DumpTimeClassInfo() {
_klass = NULL;
_nest_host = NULL;
_failed_verification = false;
_is_archived_lambda_proxy = false;
_has_checked_exclusion = false;
_id = -1 ;
_clsfile_size = -1 ;
_clsfile_crc32 = -1 ;
_excluded = false;
_is_early_klass = JvmtiExport::is_early_phase();
_verifier_constraints = NULL;
_verifier_constraint_flags = NULL;
_loader_constraints = NULL;
_enum_klass_static_fields = NULL;
}
DumpTimeClassInfo(const DumpTimeClassInfo& src);
DumpTimeClassInfo& operator =(const DumpTimeClassInfo&) = delete ;
~DumpTimeClassInfo();
void add_verification_constraint(InstanceKlass* k, Symbol* name,
Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object);
void record_linking_constraint(Symbol* name, Handle loader1, Handle loader2);
void add_enum_klass_static_field(int archived_heap_root_index);
int enum_klass_static_field(int which_field);
bool is_builtin();
private :
template <typename T>
static int array_length_or_zero(GrowableArray<T>* array) {
if (array == NULL) {
return 0 ;
} else {
return array->length();
}
}
public :
int num_verifier_constraints() const {
return array_length_or_zero(_verifier_constraint_flags);
}
int num_loader_constraints() const {
return array_length_or_zero(_loader_constraints);
}
int num_enum_klass_static_fields() const {
return array_length_or_zero(_enum_klass_static_fields);
}
void metaspace_pointers_do(MetaspaceClosure* it) {
it->push(&_klass);
it->push(&_nest_host);
if (_verifier_constraints != NULL) {
for (int i = 0 ; i < _verifier_constraints->length(); i++) {
_verifier_constraints->adr_at(i)->metaspace_pointers_do(it);
}
}
if (_loader_constraints != NULL) {
for (int i = 0 ; i < _loader_constraints->length(); i++) {
_loader_constraints->adr_at(i)->metaspace_pointers_do(it);
}
}
}
bool is_excluded() {
return _excluded || _failed_verification;
}
// Was this class loaded while JvmtiExport::is_early_phase()==true
bool is_early_klass() {
return _is_early_klass;
}
// simple accessors
void set_excluded() { _excluded = true ; }
bool has_checked_exclusion() const { return _has_checked_exclusion; }
void set_has_checked_exclusion() { _has_checked_exclusion = true ; }
bool failed_verification() const { return _failed_verification; }
void set_failed_verification() { _failed_verification = true ; }
InstanceKlass* nest_host() const { return _nest_host; }
void set_nest_host(InstanceKlass* nest_host) { _nest_host = nest_host; }
size_t runtime_info_bytesize() const ;
};
template <typename T>
inline unsigned DumpTimeSharedClassTable_hash(T* const & k) {
if (DumpSharedSpaces) {
// Deterministic archive contents
uintx delta = k->name() - MetaspaceShared::symbol_rs_base();
return primitive_hash<uintx>(delta);
} else {
// Deterministic archive is not possible because classes can be loaded
// in multiple threads.
return primitive_hash<T*>(k);
}
}
using DumpTimeSharedClassTableBaseType = ResourceHashtable<
InstanceKlass*,
DumpTimeClassInfo,
15889 , // prime number
AnyObj::C_HEAP,
mtClassShared,
&DumpTimeSharedClassTable_hash>;
class DumpTimeSharedClassTable: public DumpTimeSharedClassTableBaseType
{
int _builtin_count;
int _unregistered_count;
public :
DumpTimeSharedClassTable() {
_builtin_count = 0 ;
_unregistered_count = 0 ;
}
DumpTimeClassInfo* allocate_info(InstanceKlass* k);
DumpTimeClassInfo* get_info(InstanceKlass* k);
void inc_builtin_count() { _builtin_count++; }
void inc_unregistered_count() { _unregistered_count++; }
void update_counts();
int count_of(bool is_builtin) const {
if (is_builtin) {
return _builtin_count;
} else {
return _unregistered_count;
}
}
template <class ITER> void iterate_all_live_classes(ITER* iter) const ;
template <typename Function> void iterate_all_live_classes(Function function) const ;
private :
// It's unsafe to iterate on classes whose loader is dead.
// Declare these private and don't implement them. This forces users of
// DumpTimeSharedClassTable to use the iterate_all_live_classes() methods
// instead.
template <class ITER> void iterate(ITER* iter) const ;
template <typename Function> void iterate(Function function) const ;
template <typename Function> void iterate_all(Function function) const ;
};
#endif // SHARED_CDS_DUMPTIMESHAREDCLASSINFO_HPP
Messung V0.5 in Prozent C=95 H=100 G=97
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-09-04)
¤
*© Formatika GbR, Deutschland