Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/classfile/klassFactory.cpp
40949 views
1
/*
2
* Copyright (c) 2015, 2021, 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/filemap.hpp"
27
#include "classfile/classFileParser.hpp"
28
#include "classfile/classFileStream.hpp"
29
#include "classfile/classLoader.hpp"
30
#include "classfile/classLoaderData.hpp"
31
#include "classfile/classLoaderData.inline.hpp"
32
#include "classfile/classLoadInfo.hpp"
33
#include "classfile/klassFactory.hpp"
34
#include "memory/resourceArea.hpp"
35
#include "prims/jvmtiEnvBase.hpp"
36
#include "prims/jvmtiRedefineClasses.hpp"
37
#include "runtime/arguments.hpp"
38
#include "runtime/handles.inline.hpp"
39
#include "utilities/macros.hpp"
40
#if INCLUDE_JFR
41
#include "jfr/support/jfrKlassExtension.hpp"
42
#endif
43
44
45
// called during initial loading of a shared class
46
InstanceKlass* KlassFactory::check_shared_class_file_load_hook(
47
InstanceKlass* ik,
48
Symbol* class_name,
49
Handle class_loader,
50
Handle protection_domain,
51
const ClassFileStream *cfs,
52
TRAPS) {
53
#if INCLUDE_CDS && INCLUDE_JVMTI
54
assert(ik != NULL, "sanity");
55
assert(ik->is_shared(), "expecting a shared class");
56
if (JvmtiExport::should_post_class_file_load_hook()) {
57
58
// Post the CFLH
59
JvmtiCachedClassFileData* cached_class_file = NULL;
60
if (cfs == NULL) {
61
cfs = FileMapInfo::open_stream_for_jvmti(ik, class_loader, CHECK_NULL);
62
}
63
unsigned char* ptr = (unsigned char*)cfs->buffer();
64
unsigned char* end_ptr = ptr + cfs->length();
65
unsigned char* old_ptr = ptr;
66
JvmtiExport::post_class_file_load_hook(class_name,
67
class_loader,
68
protection_domain,
69
&ptr,
70
&end_ptr,
71
&cached_class_file);
72
if (old_ptr != ptr) {
73
// JVMTI agent has modified class file data.
74
// Set new class file stream using JVMTI agent modified class file data.
75
ClassLoaderData* loader_data =
76
ClassLoaderData::class_loader_data(class_loader());
77
int path_index = ik->shared_classpath_index();
78
ClassFileStream* stream = new ClassFileStream(ptr,
79
end_ptr - ptr,
80
cfs->source(),
81
ClassFileStream::verify);
82
ClassLoadInfo cl_info(protection_domain);
83
ClassFileParser parser(stream,
84
class_name,
85
loader_data,
86
&cl_info,
87
ClassFileParser::BROADCAST, // publicity level
88
CHECK_NULL);
89
const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr();
90
InstanceKlass* new_ik = parser.create_instance_klass(true, // changed_by_loadhook
91
*cl_inst_info, // dynamic_nest_host and classData
92
CHECK_NULL);
93
94
if (cached_class_file != NULL) {
95
new_ik->set_cached_class_file(cached_class_file);
96
}
97
98
if (class_loader.is_null()) {
99
new_ik->set_classpath_index(path_index);
100
}
101
102
return new_ik;
103
}
104
}
105
#endif
106
107
return NULL;
108
}
109
110
111
static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
112
Symbol* name,
113
ClassLoaderData* loader_data,
114
Handle protection_domain,
115
JvmtiCachedClassFileData** cached_class_file,
116
TRAPS) {
117
118
assert(stream != NULL, "invariant");
119
120
if (JvmtiExport::should_post_class_file_load_hook()) {
121
const JavaThread* jt = THREAD;
122
123
Handle class_loader(THREAD, loader_data->class_loader());
124
125
// Get the cached class file bytes (if any) from the class that
126
// is being redefined or retransformed. We use jvmti_thread_state()
127
// instead of JvmtiThreadState::state_for(jt) so we don't allocate
128
// a JvmtiThreadState any earlier than necessary. This will help
129
// avoid the bug described by 7126851.
130
131
JvmtiThreadState* state = jt->jvmti_thread_state();
132
133
if (state != NULL) {
134
Klass* k = state->get_class_being_redefined();
135
136
if (k != NULL) {
137
InstanceKlass* class_being_redefined = InstanceKlass::cast(k);
138
*cached_class_file = class_being_redefined->get_cached_class_file();
139
}
140
}
141
142
unsigned char* ptr = const_cast<unsigned char*>(stream->buffer());
143
unsigned char* end_ptr = ptr + stream->length();
144
145
JvmtiExport::post_class_file_load_hook(name,
146
class_loader,
147
protection_domain,
148
&ptr,
149
&end_ptr,
150
cached_class_file);
151
152
if (ptr != stream->buffer()) {
153
// JVMTI agent has modified class file data.
154
// Set new class file stream using JVMTI agent modified class file data.
155
stream = new ClassFileStream(ptr,
156
end_ptr - ptr,
157
stream->source(),
158
stream->need_verify());
159
}
160
}
161
162
return stream;
163
}
164
165
166
InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
167
Symbol* name,
168
ClassLoaderData* loader_data,
169
const ClassLoadInfo& cl_info,
170
TRAPS) {
171
assert(stream != NULL, "invariant");
172
assert(loader_data != NULL, "invariant");
173
174
ResourceMark rm(THREAD);
175
HandleMark hm(THREAD);
176
177
JvmtiCachedClassFileData* cached_class_file = NULL;
178
179
ClassFileStream* old_stream = stream;
180
181
// increment counter
182
THREAD->statistical_info().incr_define_class_count();
183
184
// Skip this processing for VM hidden classes
185
if (!cl_info.is_hidden()) {
186
stream = check_class_file_load_hook(stream,
187
name,
188
loader_data,
189
cl_info.protection_domain(),
190
&cached_class_file,
191
CHECK_NULL);
192
}
193
194
ClassFileParser parser(stream,
195
name,
196
loader_data,
197
&cl_info,
198
ClassFileParser::BROADCAST, // publicity level
199
CHECK_NULL);
200
201
const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr();
202
InstanceKlass* result = parser.create_instance_klass(old_stream != stream, *cl_inst_info, CHECK_NULL);
203
assert(result != NULL, "result cannot be null with no pending exception");
204
205
if (cached_class_file != NULL) {
206
// JVMTI: we have an InstanceKlass now, tell it about the cached bytes
207
result->set_cached_class_file(cached_class_file);
208
}
209
210
JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
211
212
#if INCLUDE_CDS
213
if (Arguments::is_dumping_archive()) {
214
ClassLoader::record_result(THREAD, result, stream);
215
}
216
#endif // INCLUDE_CDS
217
218
return result;
219
}
220
221