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.
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.
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).
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.
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
25
#include "precompiled.hpp"
26
#include "cds/archiveBuilder.hpp"
27
#include "cds/dumpTimeClassInfo.inline.hpp"
28
#include "cds/runTimeClassInfo.hpp"
29
#include "classfile/classLoader.hpp"
30
#include "classfile/classLoaderData.inline.hpp"
31
#include "classfile/systemDictionaryShared.hpp"
32
#include "memory/resourceArea.hpp"
34
DumpTimeClassInfo::~DumpTimeClassInfo() {
35
if (_verifier_constraints != nullptr) {
36
assert(_verifier_constraint_flags != nullptr, "must be");
37
delete _verifier_constraints;
38
delete _verifier_constraint_flags;
40
if (_loader_constraints != nullptr) {
41
delete _loader_constraints;
45
size_t DumpTimeClassInfo::runtime_info_bytesize() const {
46
return RunTimeClassInfo::byte_size(_klass, num_verifier_constraints(),
47
num_loader_constraints(),
48
num_enum_klass_static_fields());
51
void DumpTimeClassInfo::add_verification_constraint(InstanceKlass* k, Symbol* name,
52
Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
53
if (_verifier_constraints == nullptr) {
54
_verifier_constraints = new (mtClass) GrowableArray<DTVerifierConstraint>(4, mtClass);
56
if (_verifier_constraint_flags == nullptr) {
57
_verifier_constraint_flags = new (mtClass) GrowableArray<char>(4, mtClass);
59
GrowableArray<DTVerifierConstraint>* vc_array = _verifier_constraints;
60
for (int i = 0; i < vc_array->length(); i++) {
61
if (vc_array->at(i).equals(name, from_name)) {
65
DTVerifierConstraint cons(name, from_name);
66
vc_array->append(cons);
68
GrowableArray<char>* vcflags_array = _verifier_constraint_flags;
70
c |= from_field_is_protected ? SystemDictionaryShared::FROM_FIELD_IS_PROTECTED : 0;
71
c |= from_is_array ? SystemDictionaryShared::FROM_IS_ARRAY : 0;
72
c |= from_is_object ? SystemDictionaryShared::FROM_IS_OBJECT : 0;
73
vcflags_array->append(c);
75
if (log_is_enabled(Trace, cds, verification)) {
77
log_trace(cds, verification)("add_verification_constraint: %s: %s must be subclass of %s [0x%x] array len %d flags len %d",
78
k->external_name(), from_name->as_klass_external_name(),
79
name->as_klass_external_name(), c, vc_array->length(), vcflags_array->length());
83
static char get_loader_type_by(oop loader) {
84
assert(SystemDictionary::is_builtin_class_loader(loader), "Must be built-in loader");
85
if (SystemDictionary::is_boot_class_loader(loader)) {
86
return (char)ClassLoader::BOOT_LOADER;
87
} else if (SystemDictionary::is_platform_class_loader(loader)) {
88
return (char)ClassLoader::PLATFORM_LOADER;
90
assert(SystemDictionary::is_system_class_loader(loader), "Class loader mismatch");
91
return (char)ClassLoader::APP_LOADER;
95
void DumpTimeClassInfo::record_linking_constraint(Symbol* name, Handle loader1, Handle loader2) {
96
assert(loader1 != loader2, "sanity");
97
LogTarget(Info, class, loader, constraints) log;
98
if (_loader_constraints == nullptr) {
99
_loader_constraints = new (mtClass) GrowableArray<DTLoaderConstraint>(4, mtClass);
101
char lt1 = get_loader_type_by(loader1());
102
char lt2 = get_loader_type_by(loader2());
103
DTLoaderConstraint lc(name, lt1, lt2);
104
for (int i = 0; i < _loader_constraints->length(); i++) {
105
if (lc.equals(_loader_constraints->at(i))) {
106
if (log.is_enabled()) {
108
// Use loader[0]/loader[1] to be consistent with the logs in loaderConstraints.cpp
109
log.print("[CDS record loader constraint for class: %s constraint_name: %s loader[0]: %s loader[1]: %s already added]",
110
_klass->external_name(), name->as_C_string(),
111
ClassLoaderData::class_loader_data(loader1())->loader_name_and_id(),
112
ClassLoaderData::class_loader_data(loader2())->loader_name_and_id());
117
_loader_constraints->append(lc);
118
if (log.is_enabled()) {
120
// Use loader[0]/loader[1] to be consistent with the logs in loaderConstraints.cpp
121
log.print("[CDS record loader constraint for class: %s constraint_name: %s loader[0]: %s loader[1]: %s total %d]",
122
_klass->external_name(), name->as_C_string(),
123
ClassLoaderData::class_loader_data(loader1())->loader_name_and_id(),
124
ClassLoaderData::class_loader_data(loader2())->loader_name_and_id(),
125
_loader_constraints->length());
129
void DumpTimeClassInfo::add_enum_klass_static_field(int archived_heap_root_index) {
130
if (_enum_klass_static_fields == nullptr) {
131
_enum_klass_static_fields = new (mtClass) GrowableArray<int>(20, mtClass);
133
_enum_klass_static_fields->append(archived_heap_root_index);
136
int DumpTimeClassInfo::enum_klass_static_field(int which_field) {
137
assert(_enum_klass_static_fields != nullptr, "must be");
138
return _enum_klass_static_fields->at(which_field);
141
bool DumpTimeClassInfo::is_builtin() {
142
return SystemDictionaryShared::is_builtin(_klass);
145
DumpTimeClassInfo* DumpTimeSharedClassTable::allocate_info(InstanceKlass* k) {
146
assert(!k->is_shared(), "Do not call with shared classes");
148
DumpTimeClassInfo* p = put_if_absent(k, &created);
149
assert(created, "must not exist in table");
154
DumpTimeClassInfo* DumpTimeSharedClassTable::get_info(InstanceKlass* k) {
155
assert(!k->is_shared(), "Do not call with shared classes");
156
DumpTimeClassInfo* p = get(k);
157
assert(p != nullptr, "we must not see any non-shared InstanceKlass* that's "
158
"not stored with SystemDictionaryShared::init_dumptime_info");
159
assert(p->_klass == k, "Sanity");
163
class CountClassByCategory : StackObj {
164
DumpTimeSharedClassTable* _table;
166
CountClassByCategory(DumpTimeSharedClassTable* table) : _table(table) {}
167
void do_entry(InstanceKlass* k, DumpTimeClassInfo& info) {
168
if (!info.is_excluded()) {
169
if (info.is_builtin()) {
170
_table->inc_builtin_count();
172
_table->inc_unregistered_count();
178
void DumpTimeSharedClassTable::update_counts() {
180
_unregistered_count = 0;
181
CountClassByCategory counter(this);
182
iterate_all_live_classes(&counter);