1 /* 2 * Copyright (c) 2015, 2018, 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 "classfile/classFileParser.hpp" 27 #include "classfile/classFileStream.hpp" 28 #include "classfile/classLoader.hpp" 29 #include "classfile/classLoaderData.hpp" 30 #include "classfile/classLoaderData.inline.hpp" 31 #include "classfile/klassFactory.hpp" 32 #include "classfile/sharedClassUtil.hpp" 33 #include "memory/metaspaceShared.hpp" 34 #include "memory/resourceArea.hpp" 35 #include "prims/jvmtiEnvBase.hpp" 36 #include "prims/jvmtiRedefineClasses.hpp" 37 #include "runtime/handles.inline.hpp" 38 #include "trace/traceMacros.hpp" 39 40 // called during initial loading of a shared class 41 InstanceKlass* KlassFactory::check_shared_class_file_load_hook( 42 InstanceKlass* ik, 43 Symbol* class_name, 44 Handle class_loader, 45 Handle protection_domain, TRAPS) { 46 #if INCLUDE_CDS && INCLUDE_JVMTI 47 assert(ik != NULL, "sanity"); 48 assert(ik->is_shared(), "expecting a shared class"); 49 50 if (JvmtiExport::should_post_class_file_load_hook()) { 51 assert(THREAD->is_Java_thread(), "must be JavaThread"); 52 53 // Post the CFLH 54 JvmtiCachedClassFileData* cached_class_file = NULL; 55 JvmtiCachedClassFileData* archived_class_data = ik->get_archived_class_data(); 56 assert(archived_class_data != NULL, "shared class has no archived class data"); 57 unsigned char* ptr = 58 VM_RedefineClasses::get_cached_class_file_bytes(archived_class_data); 59 unsigned char* end_ptr = 60 ptr + VM_RedefineClasses::get_cached_class_file_len(archived_class_data); 61 unsigned char* old_ptr = ptr; 62 JvmtiExport::post_class_file_load_hook(class_name, 63 class_loader, 64 protection_domain, 65 &ptr, 66 &end_ptr, 67 &cached_class_file); 68 if (old_ptr != ptr) { 69 // JVMTI agent has modified class file data. 70 // Set new class file stream using JVMTI agent modified class file data. 71 ClassLoaderData* loader_data = 72 ClassLoaderData::class_loader_data(class_loader()); 73 int path_index = ik->shared_classpath_index(); 74 const char* pathname; 75 if (path_index < 0) { 76 // shared classes loaded by user defined class loader 77 // do not have shared_classpath_index 78 ModuleEntry* mod_entry = ik->module(); 79 if (mod_entry != NULL && (mod_entry->location() != NULL)) { 80 ResourceMark rm; 81 pathname = (const char*)(mod_entry->location()->as_C_string()); 82 } else { 83 pathname = ""; 84 } 85 } else { 86 SharedClassPathEntry* ent = 87 (SharedClassPathEntry*)FileMapInfo::shared_path(path_index); 88 pathname = ent == NULL ? NULL : ent->name(); 89 } 90 ClassFileStream* stream = new ClassFileStream(ptr, 91 end_ptr - ptr, 92 pathname, 93 ClassFileStream::verify); 94 ClassFileParser parser(stream, 95 class_name, 96 loader_data, 97 protection_domain, 98 NULL, 99 NULL, 100 ClassFileParser::BROADCAST, // publicity level 101 CHECK_NULL); 102 InstanceKlass* new_ik = parser.create_instance_klass(true /* changed_by_loadhook */, 103 CHECK_NULL); 104 if (cached_class_file != NULL) { 105 new_ik->set_cached_class_file(cached_class_file); 106 } 107 108 if (class_loader.is_null()) { 109 ResourceMark rm; 110 ClassLoader::add_package(class_name->as_C_string(), path_index, THREAD); 111 } 112 113 return new_ik; 114 } 115 } 116 #endif 117 118 return NULL; 119 } 120 121 122 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, 123 Symbol* name, 124 ClassLoaderData* loader_data, 125 Handle protection_domain, 126 JvmtiCachedClassFileData** cached_class_file, 127 TRAPS) { 128 129 assert(stream != NULL, "invariant"); 130 131 if (JvmtiExport::should_post_class_file_load_hook()) { 132 assert(THREAD->is_Java_thread(), "must be a JavaThread"); 133 const JavaThread* jt = (JavaThread*)THREAD; 134 135 Handle class_loader(THREAD, loader_data->class_loader()); 136 137 // Get the cached class file bytes (if any) from the class that 138 // is being redefined or retransformed. We use jvmti_thread_state() 139 // instead of JvmtiThreadState::state_for(jt) so we don't allocate 140 // a JvmtiThreadState any earlier than necessary. This will help 141 // avoid the bug described by 7126851. 142 143 JvmtiThreadState* state = jt->jvmti_thread_state(); 144 145 if (state != NULL) { 146 Klass* k = state->get_class_being_redefined(); 147 148 if (k != NULL) { 149 InstanceKlass* class_being_redefined = InstanceKlass::cast(k); 150 *cached_class_file = class_being_redefined->get_cached_class_file(); 151 } 152 } 153 154 unsigned char* ptr = const_cast<unsigned char*>(stream->buffer()); 155 unsigned char* end_ptr = ptr + stream->length(); 156 157 JvmtiExport::post_class_file_load_hook(name, 158 class_loader, 159 protection_domain, 160 &ptr, 161 &end_ptr, 162 cached_class_file); 163 164 if (ptr != stream->buffer()) { 165 // JVMTI agent has modified class file data. 166 // Set new class file stream using JVMTI agent modified class file data. 167 stream = new ClassFileStream(ptr, 168 end_ptr - ptr, 169 stream->source(), 170 stream->need_verify()); 171 } 172 } 173 174 return stream; 175 } 176 177 178 InstanceKlass* KlassFactory::create_from_stream(ClassFileStream* stream, 179 Symbol* name, 180 ClassLoaderData* loader_data, 181 Handle protection_domain, 182 const InstanceKlass* host_klass, 183 GrowableArray<Handle>* cp_patches, 184 TRAPS) { 185 assert(stream != NULL, "invariant"); 186 assert(loader_data != NULL, "invariant"); 187 assert(THREAD->is_Java_thread(), "must be a JavaThread"); 188 189 ResourceMark rm; 190 HandleMark hm; 191 192 JvmtiCachedClassFileData* cached_class_file = NULL; 193 194 ClassFileStream* old_stream = stream; 195 196 // Skip this processing for VM anonymous classes 197 if (host_klass == NULL) { 198 stream = check_class_file_load_hook(stream, 199 name, 200 loader_data, 201 protection_domain, 202 &cached_class_file, 203 CHECK_NULL); 204 } 205 206 ClassFileParser parser(stream, 207 name, 208 loader_data, 209 protection_domain, 210 host_klass, 211 cp_patches, 212 ClassFileParser::BROADCAST, // publicity level 213 CHECK_NULL); 214 215 InstanceKlass* result = parser.create_instance_klass(old_stream != stream, CHECK_NULL); 216 assert(result == parser.create_instance_klass(old_stream != stream, THREAD), "invariant"); 217 218 if (result == NULL) { 219 return NULL; 220 } 221 222 if (cached_class_file != NULL) { 223 // JVMTI: we have an InstanceKlass now, tell it about the cached bytes 224 result->set_cached_class_file(cached_class_file); 225 } 226 227 if (result->should_store_fingerprint()) { 228 result->store_fingerprint(stream->compute_fingerprint()); 229 } 230 231 TRACE_KLASS_CREATION(result, parser, THREAD); 232 233 #if INCLUDE_CDS 234 if (DumpSharedSpaces) { 235 ClassLoader::record_result(result, stream); 236 #if INCLUDE_JVMTI 237 assert(cached_class_file == NULL, "Sanity"); 238 // Archive the class stream data into the optional data section 239 JvmtiCachedClassFileData *p; 240 int len; 241 const unsigned char *bytes; 242 // event based tracing might set cached_class_file 243 if ((bytes = result->get_cached_class_file_bytes()) != NULL) { 244 len = result->get_cached_class_file_len(); 245 } else { 246 len = stream->length(); 247 bytes = stream->buffer(); 248 } 249 p = (JvmtiCachedClassFileData*)os::malloc(offset_of(JvmtiCachedClassFileData, data) + len, mtInternal); 250 p->length = len; 251 memcpy(p->data, bytes, len); 252 result->set_archived_class_data(p); 253 #endif // INCLUDE_JVMTI 254 } 255 #endif // INCLUDE_CDS 256 257 return result; 258 }