jdk

Форк
0
/
dumpTimeClassInfo.cpp 
183 строки · 7.2 Кб
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
 *
23
 */
24

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"
33

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;
39
  }
40
  if (_loader_constraints != nullptr) {
41
    delete _loader_constraints;
42
  }
43
}
44

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());
49
}
50

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);
55
  }
56
  if (_verifier_constraint_flags == nullptr) {
57
    _verifier_constraint_flags = new (mtClass) GrowableArray<char>(4, mtClass);
58
  }
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)) {
62
      return;
63
    }
64
  }
65
  DTVerifierConstraint cons(name, from_name);
66
  vc_array->append(cons);
67

68
  GrowableArray<char>* vcflags_array = _verifier_constraint_flags;
69
  char c = 0;
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);
74

75
  if (log_is_enabled(Trace, cds, verification)) {
76
    ResourceMark rm;
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());
80
  }
81
}
82

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;
89
  } else {
90
    assert(SystemDictionary::is_system_class_loader(loader), "Class loader mismatch");
91
    return (char)ClassLoader::APP_LOADER;
92
  }
93
}
94

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);
100
  }
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()) {
107
        ResourceMark rm;
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());
113
      }
114
      return;
115
    }
116
  }
117
  _loader_constraints->append(lc);
118
  if (log.is_enabled()) {
119
    ResourceMark rm;
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());
126
  }
127
}
128

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);
132
  }
133
  _enum_klass_static_fields->append(archived_heap_root_index);
134
}
135

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);
139
}
140

141
bool DumpTimeClassInfo::is_builtin() {
142
  return SystemDictionaryShared::is_builtin(_klass);
143
}
144

145
DumpTimeClassInfo* DumpTimeSharedClassTable::allocate_info(InstanceKlass* k) {
146
  assert(!k->is_shared(), "Do not call with shared classes");
147
  bool created;
148
  DumpTimeClassInfo* p = put_if_absent(k, &created);
149
  assert(created, "must not exist in table");
150
  p->_klass = k;
151
  return p;
152
}
153

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");
160
  return p;
161
}
162

163
class CountClassByCategory : StackObj {
164
  DumpTimeSharedClassTable* _table;
165
public:
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();
171
      } else {
172
        _table->inc_unregistered_count();
173
      }
174
    }
175
  }
176
};
177

178
void DumpTimeSharedClassTable::update_counts() {
179
  _builtin_count = 0;
180
  _unregistered_count = 0;
181
  CountClassByCategory counter(this);
182
  iterate_all_live_classes(&counter);
183
}
184

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.