1 /* 2 * Copyright (c) 2015, 2016, 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/classLoaderData.hpp" 29 #include "classfile/classLoaderData.inline.hpp" 30 #include "classfile/klassFactory.hpp" 31 #include "classfile/sharedClassUtil.hpp" 32 #include "memory/metaspaceShared.hpp" 33 #include "memory/resourceArea.hpp" 34 #include "prims/jvmtiEnvBase.hpp" 35 #include "prims/jvmtiRedefineClasses.hpp" 36 #include "trace/traceMacros.hpp" 37 38 // called during initial loading of a shared class 39 instanceKlassHandle KlassFactory::check_shared_class_file_load_hook( 40 instanceKlassHandle ik, 41 Symbol* class_name, 42 Handle class_loader, 43 Handle protection_domain, TRAPS) { 44 instanceKlassHandle nh = instanceKlassHandle(); 45 46 #if INCLUDE_CDS && INCLUDE_JVMTI 47 assert(ik.not_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 SharedClassPathEntry* ent = 75 (SharedClassPathEntry*)FileMapInfo::shared_classpath(path_index); 76 ClassFileStream* stream = new ClassFileStream(ptr, 77 end_ptr - ptr, 78 ent->_name, 79 ClassFileStream::verify); 80 ClassFileParser parser(stream, 81 class_name, 82 loader_data, 83 protection_domain, 84 NULL, 85 NULL, 86 ClassFileParser::BROADCAST, // publicity level 87 CHECK_(nh)); 88 instanceKlassHandle new_ik = parser.create_instance_klass(true /* changed_by_loadhook */, 89 CHECK_(nh)); 90 if (cached_class_file != NULL) { 91 new_ik->set_cached_class_file(cached_class_file); 92 } 93 return new_ik; 94 } 95 } 96 #endif 97 98 return nh; 99 } 100 101 102 static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream, 103 Symbol* name, 104 ClassLoaderData* loader_data, 105 Handle protection_domain, 106 JvmtiCachedClassFileData** cached_class_file, 107 TRAPS) { 108 109 assert(stream != NULL, "invariant"); 110 111 if (JvmtiExport::should_post_class_file_load_hook()) { 112 assert(THREAD->is_Java_thread(), "must be a JavaThread"); 113 const JavaThread* jt = (JavaThread*)THREAD; 114 115 Handle class_loader(THREAD, loader_data->class_loader()); 116 117 // Get the cached class file bytes (if any) from the class that 118 // is being redefined or retransformed. We use jvmti_thread_state() 119 // instead of JvmtiThreadState::state_for(jt) so we don't allocate 120 // a JvmtiThreadState any earlier than necessary. This will help 121 // avoid the bug described by 7126851. 122 123 JvmtiThreadState* state = jt->jvmti_thread_state(); 124 125 if (state != NULL) { 126 KlassHandle* h_class_being_redefined = 127 state->get_class_being_redefined(); 128 129 if (h_class_being_redefined != NULL) { 130 instanceKlassHandle ikh_class_being_redefined = 131 instanceKlassHandle(THREAD, (*h_class_being_redefined)()); 132 133 *cached_class_file = ikh_class_being_redefined->get_cached_class_file(); 134 } 135 } 136 137 unsigned char* ptr = const_cast<unsigned char*>(stream->buffer()); 138 unsigned char* end_ptr = ptr + stream->length(); 139 140 JvmtiExport::post_class_file_load_hook(name, 141 class_loader, 142 protection_domain, 143 &ptr, 144 &end_ptr, 145 cached_class_file); 146 147 if (ptr != stream->buffer()) { 148 // JVMTI agent has modified class file data. 149 // Set new class file stream using JVMTI agent modified class file data. 150 stream = new ClassFileStream(ptr, 151 end_ptr - ptr, 152 stream->source(), 153 stream->need_verify()); 154 } 155 } 156 157 return stream; 158 } 159 160 161 instanceKlassHandle KlassFactory::create_from_stream(ClassFileStream* stream, 162 Symbol* name, 163 ClassLoaderData* loader_data, 164 Handle protection_domain, 165 const Klass* host_klass, 166 GrowableArray<Handle>* cp_patches, 167 TRAPS) { 168 assert(stream != NULL, "invariant"); 169 assert(loader_data != NULL, "invariant"); 170 assert(THREAD->is_Java_thread(), "must be a JavaThread"); 171 172 ResourceMark rm; 173 HandleMark hm; 174 175 JvmtiCachedClassFileData* cached_class_file = NULL; 176 177 ClassFileStream* old_stream = stream; 178 179 // Skip this processing for VM anonymous classes 180 if (host_klass == NULL) { 181 stream = check_class_file_load_hook(stream, 182 name, 183 loader_data, 184 protection_domain, 185 &cached_class_file, 186 CHECK_NULL); 187 } 188 189 ClassFileParser parser(stream, 190 name, 191 loader_data, 192 protection_domain, 193 host_klass, 194 cp_patches, 195 ClassFileParser::BROADCAST, // publicity level 196 CHECK_NULL); 197 198 instanceKlassHandle result = parser.create_instance_klass(old_stream != stream, CHECK_NULL); 199 assert(result == parser.create_instance_klass(old_stream != stream, THREAD), "invariant"); 200 201 if (result.is_null()) { 202 return NULL; 203 } 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 TRACE_KLASS_CREATION(result, parser, THREAD); 211 212 #if INCLUDE_CDS && INCLUDE_JVMTI 213 if (DumpSharedSpaces) { 214 assert(cached_class_file == NULL, "Sanity"); 215 // Archive the class stream data into the optional data section 216 JvmtiCachedClassFileData *p; 217 int len; 218 const unsigned char *bytes; 219 if ((result->get_cached_class_file()) != NULL) { 220 // JFR might set cached_class_file 221 len = result->get_cached_class_file_len(); 222 bytes = result->get_cached_class_file_bytes(); 223 } else { 224 len = stream->length(); 225 bytes = stream->buffer(); 226 } 227 p = (JvmtiCachedClassFileData*)MetaspaceShared::optional_data_space_alloc( 228 offset_of(JvmtiCachedClassFileData, data) + len); 229 p->length = len; 230 memcpy(p->data, bytes, len); 231 result->set_archived_class_data(p); 232 } 233 #endif 234 235 return result; 236 }