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 }