< prev index next >

src/hotspot/share/classfile/klassFactory.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com
   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 }
< prev index next >