1 /*
2 * Copyright (c) 2015, 2019, 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 *
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 ClassFileParser parser(stream,
83 class_name,
84 loader_data,
85 protection_domain,
86 NULL,
87 NULL,
88 ClassFileParser::BROADCAST, // publicity level
89 CHECK_NULL);
90 InstanceKlass* new_ik = parser.create_instance_klass(true /* changed_by_loadhook */,
91 CHECK_NULL);
92 if (cached_class_file != NULL) {
93 new_ik->set_cached_class_file(cached_class_file);
94 }
95
96 if (class_loader.is_null()) {
97 ClassLoader::add_package(new_ik, path_index, THREAD);
98 }
99
100 return new_ik;
101 }
102 }
103 #endif
104
105 return NULL;
106 }
107
108
109 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
110 Symbol* name,
111 ClassLoaderData* loader_data,
148 &end_ptr,
149 cached_class_file);
150
151 if (ptr != stream->buffer()) {
152 // JVMTI agent has modified class file data.
153 // Set new class file stream using JVMTI agent modified class file data.
154 stream = new ClassFileStream(ptr,
155 end_ptr - ptr,
156 stream->source(),
157 stream->need_verify());
158 }
159 }
160
161 return stream;
162 }
163
164
165 InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
166 Symbol* name,
167 ClassLoaderData* loader_data,
168 Handle protection_domain,
169 const InstanceKlass* unsafe_anonymous_host,
170 GrowableArray<Handle>* cp_patches,
171 TRAPS) {
172 assert(stream != NULL, "invariant");
173 assert(loader_data != NULL, "invariant");
174 assert(THREAD->is_Java_thread(), "must be a JavaThread");
175
176 ResourceMark rm;
177 HandleMark hm;
178
179 JvmtiCachedClassFileData* cached_class_file = NULL;
180
181 ClassFileStream* old_stream = stream;
182
183 // increment counter
184 THREAD->statistical_info().incr_define_class_count();
185
186 // Skip this processing for VM anonymous classes
187 if (unsafe_anonymous_host == NULL) {
188 stream = check_class_file_load_hook(stream,
189 name,
190 loader_data,
191 protection_domain,
192 &cached_class_file,
193 CHECK_NULL);
194 }
195
196 ClassFileParser parser(stream,
197 name,
198 loader_data,
199 protection_domain,
200 unsafe_anonymous_host,
201 cp_patches,
202 ClassFileParser::BROADCAST, // publicity level
203 CHECK_NULL);
204
205 InstanceKlass* result = parser.create_instance_klass(old_stream != stream, CHECK_NULL);
206 assert(result == parser.create_instance_klass(old_stream != stream, THREAD), "invariant");
207
208 if (result == NULL) {
209 return NULL;
210 }
211
212 if (cached_class_file != NULL) {
213 // JVMTI: we have an InstanceKlass now, tell it about the cached bytes
214 result->set_cached_class_file(cached_class_file);
215 }
216
217 JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
218
219 #if INCLUDE_CDS
220 if (Arguments::is_dumping_archive()) {
221 ClassLoader::record_result(result, stream, THREAD);
222 }
223 #endif // INCLUDE_CDS
224
225 return result;
226 }
|
1 /*
2 * Copyright (c) 2015, 2020, 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 *
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 ClassLoader::add_package(new_ik, path_index, THREAD);
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,
150 &end_ptr,
151 cached_class_file);
152
153 if (ptr != stream->buffer()) {
154 // JVMTI agent has modified class file data.
155 // Set new class file stream using JVMTI agent modified class file data.
156 stream = new ClassFileStream(ptr,
157 end_ptr - ptr,
158 stream->source(),
159 stream->need_verify());
160 }
161 }
162
163 return stream;
164 }
165
166
167 InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream,
168 Symbol* name,
169 ClassLoaderData* loader_data,
170 const ClassLoadInfo& cl_info,
171 TRAPS) {
172 assert(stream != NULL, "invariant");
173 assert(loader_data != NULL, "invariant");
174 assert(THREAD->is_Java_thread(), "must be a JavaThread");
175
176 ResourceMark rm;
177 HandleMark hm;
178
179 JvmtiCachedClassFileData* cached_class_file = NULL;
180
181 ClassFileStream* old_stream = stream;
182
183 // increment counter
184 THREAD->statistical_info().incr_define_class_count();
185
186 assert(!(cl_info.is_hidden() && (cl_info.unsafe_anonymous_host() != NULL)),
187 "hidden class has an anonymous host");
188
189 // Skip this processing for VM hidden or anonymous classes
190 if (!cl_info.is_hidden() && (cl_info.unsafe_anonymous_host() == NULL)) {
191 stream = check_class_file_load_hook(stream,
192 name,
193 loader_data,
194 cl_info.protection_domain(),
195 &cached_class_file,
196 CHECK_NULL);
197 }
198
199 ClassFileParser parser(stream,
200 name,
201 loader_data,
202 &cl_info,
203 ClassFileParser::BROADCAST, // publicity level
204 CHECK_NULL);
205
206 const ClassInstanceInfo* cl_inst_info = cl_info.class_hidden_info_ptr();
207 InstanceKlass* result = parser.create_instance_klass(old_stream != stream, *cl_inst_info, CHECK_NULL);
208
209 if (result == NULL) {
210 return NULL;
211 }
212
213 if (cached_class_file != NULL) {
214 // JVMTI: we have an InstanceKlass now, tell it about the cached bytes
215 result->set_cached_class_file(cached_class_file);
216 }
217
218 JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
219
220 #if INCLUDE_CDS
221 if (Arguments::is_dumping_archive()) {
222 ClassLoader::record_result(result, stream, THREAD);
223 }
224 #endif // INCLUDE_CDS
225
226 return result;
227 }
|