23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "classfile/classFileParser.hpp" |
26 #include "classfile/classFileParser.hpp" |
27 #include "classfile/classFileStream.hpp" |
27 #include "classfile/classFileStream.hpp" |
|
28 #include "classfile/classLoader.hpp" |
28 #include "classfile/classLoaderData.hpp" |
29 #include "classfile/classLoaderData.hpp" |
|
30 #include "classfile/classLoaderData.inline.hpp" |
29 #include "classfile/klassFactory.hpp" |
31 #include "classfile/klassFactory.hpp" |
|
32 #include "classfile/sharedClassUtil.hpp" |
|
33 #include "memory/metaspaceShared.hpp" |
30 #include "memory/resourceArea.hpp" |
34 #include "memory/resourceArea.hpp" |
31 #include "prims/jvmtiEnvBase.hpp" |
35 #include "prims/jvmtiEnvBase.hpp" |
|
36 #include "prims/jvmtiRedefineClasses.hpp" |
32 #include "trace/traceMacros.hpp" |
37 #include "trace/traceMacros.hpp" |
|
38 |
|
39 // called during initial loading of a shared class |
|
40 instanceKlassHandle KlassFactory::check_shared_class_file_load_hook( |
|
41 instanceKlassHandle ik, |
|
42 Symbol* class_name, |
|
43 Handle class_loader, |
|
44 Handle protection_domain, TRAPS) { |
|
45 #if INCLUDE_CDS && INCLUDE_JVMTI |
|
46 assert(ik.not_null(), "sanity"); |
|
47 assert(ik()->is_shared(), "expecting a shared class"); |
|
48 |
|
49 if (JvmtiExport::should_post_class_file_load_hook()) { |
|
50 assert(THREAD->is_Java_thread(), "must be JavaThread"); |
|
51 |
|
52 // Post the CFLH |
|
53 JvmtiCachedClassFileData* cached_class_file = NULL; |
|
54 JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data(); |
|
55 assert(archived_class_data != NULL, "shared class has no archived class data"); |
|
56 unsigned char* ptr = |
|
57 VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data); |
|
58 unsigned char* end_ptr = |
|
59 ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data); |
|
60 unsigned char* old_ptr = ptr; |
|
61 JvmtiExport::post_class_file_load_hook(class_name, |
|
62 class_loader, |
|
63 protection_domain, |
|
64 &ptr, |
|
65 &end_ptr, |
|
66 &cached_class_file); |
|
67 if (old_ptr != ptr) { |
|
68 // JVMTI agent has modified class file data. |
|
69 // Set new class file stream using JVMTI agent modified class file data. |
|
70 ClassLoaderData* loader_data = |
|
71 ClassLoaderData::class_loader_data(class_loader()); |
|
72 int path_index = ik->shared_classpath_index(); |
|
73 SharedClassPathEntry* ent = |
|
74 (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index); |
|
75 ClassFileStream* stream = new ClassFileStream(ptr, |
|
76 end_ptr - ptr, |
|
77 ent->_name, |
|
78 ClassFileStream::verify); |
|
79 ClassFileParser parser(stream, |
|
80 class_name, |
|
81 loader_data, |
|
82 protection_domain, |
|
83 NULL, |
|
84 NULL, |
|
85 ClassFileParser::BROADCAST, // publicity level |
|
86 CHECK_NULL); |
|
87 instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */, |
|
88 CHECK_NULL); |
|
89 if (cached_class_file != NULL) { |
|
90 new_ik->set_cached_class_file(cached_class_file); |
|
91 } |
|
92 |
|
93 if (class_loader.is_null()) { |
|
94 ResourceMark rm; |
|
95 ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD); |
|
96 } |
|
97 |
|
98 return new_ik; |
|
99 } |
|
100 } |
|
101 #endif |
|
102 |
|
103 return NULL; |
|
104 } |
|
105 |
33 |
106 |
34 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, |
107 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, |
35 Symbol* name, |
108 Symbol* name, |
36 ClassLoaderData* loader_data, |
109 ClassLoaderData* loader_data, |
37 Handle protection_domain, |
110 Handle protection_domain, |
95 ClassLoaderData* loader_data, |
168 ClassLoaderData* loader_data, |
96 Handle protection_domain, |
169 Handle protection_domain, |
97 const InstanceKlass* host_klass, |
170 const InstanceKlass* host_klass, |
98 GrowableArray<Handle>* cp_patches, |
171 GrowableArray<Handle>* cp_patches, |
99 TRAPS) { |
172 TRAPS) { |
100 |
|
101 assert(stream != NULL, "invariant"); |
173 assert(stream != NULL, "invariant"); |
102 assert(loader_data != NULL, "invariant"); |
174 assert(loader_data != NULL, "invariant"); |
103 assert(THREAD->is_Java_thread(), "must be a JavaThread"); |
175 assert(THREAD->is_Java_thread(), "must be a JavaThread"); |
104 |
176 |
105 ResourceMark rm; |
177 ResourceMark rm; |
140 result->set_cached_class_file(cached_class_file); |
212 result->set_cached_class_file(cached_class_file); |
141 } |
213 } |
142 |
214 |
143 TRACE_KLASS_CREATION(result, parser, THREAD); |
215 TRACE_KLASS_CREATION(result, parser, THREAD); |
144 |
216 |
|
217 #if INCLUDE_CDS && INCLUDE_JVMTI |
|
218 if (DumpSharedSpaces) { |
|
219 assert(cached_class_file == NULL, "Sanity"); |
|
220 // Archive the class stream data into the optional data section |
|
221 JvmtiCachedClassFileData *p; |
|
222 int len; |
|
223 const unsigned char *bytes; |
|
224 // event based tracing might set cached_class_file |
|
225 if ((bytes = result->get_cached_class_file_bytes()) != NULL) { |
|
226 len = result->get_cached_class_file_len(); |
|
227 } else { |
|
228 len = stream->length(); |
|
229 bytes = stream->buffer(); |
|
230 } |
|
231 p = (JvmtiCachedClassFileData*)MetaspaceShared::optional_data_space_alloc( |
|
232 offset_of(JvmtiCachedClassFileData, data) + len); |
|
233 p->length = len; |
|
234 memcpy(p->data, bytes, len); |
|
235 result->set_archived_class_data(p); |
|
236 } |
|
237 #endif |
|
238 |
145 return result; |
239 return result; |
146 } |
240 } |