< prev index next >

src/hotspot/share/classfile/systemDictionaryShared.cpp

Print this page


  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/classFileStream.hpp"
  27 #include "classfile/classListParser.hpp"
  28 #include "classfile/classLoader.hpp"
  29 #include "classfile/classLoaderData.inline.hpp"
  30 #include "classfile/classLoaderExt.hpp"
  31 #include "classfile/compactHashtable.inline.hpp"
  32 #include "classfile/dictionary.hpp"
  33 #include "classfile/javaClasses.hpp"
  34 #include "classfile/sharedClassUtil.hpp"
  35 #include "classfile/symbolTable.hpp"
  36 #include "classfile/systemDictionary.hpp"
  37 #include "classfile/systemDictionaryShared.hpp"
  38 #include "classfile/verificationType.hpp"
  39 #include "classfile/vmSymbols.hpp"
  40 #include "logging/log.hpp"
  41 #include "memory/allocation.hpp"
  42 #include "memory/filemap.hpp"
  43 #include "memory/metadataFactory.hpp"
  44 #include "memory/metaspaceClosure.hpp"
  45 #include "memory/oopFactory.hpp"
  46 #include "memory/resourceArea.hpp"
  47 #include "oops/instanceKlass.hpp"
  48 #include "oops/klass.inline.hpp"
  49 #include "oops/objArrayOop.inline.hpp"
  50 #include "oops/oop.inline.hpp"
  51 #include "oops/typeArrayOop.inline.hpp"
  52 #include "runtime/handles.inline.hpp"
  53 #include "runtime/java.hpp"
  54 #include "runtime/javaCalls.hpp"


  75   }
  76 }
  77 
  78 oop SystemDictionaryShared::shared_protection_domain(int index) {
  79   return _shared_protection_domains->obj_at(index);
  80 }
  81 
  82 oop SystemDictionaryShared::shared_jar_url(int index) {
  83   return _shared_jar_urls->obj_at(index);
  84 }
  85 
  86 oop SystemDictionaryShared::shared_jar_manifest(int index) {
  87   return _shared_jar_manifests->obj_at(index);
  88 }
  89 
  90 
  91 Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TRAPS) {
  92   Handle empty;
  93   Handle manifest ;
  94   if (shared_jar_manifest(shared_path_index) == NULL) {
  95     SharedClassPathEntryExt* ent = (SharedClassPathEntryExt*)FileMapInfo::shared_path(shared_path_index);
  96     long size = ent->manifest_size();
  97     if (size <= 0) {
  98       return empty; // No manifest - return NULL handle
  99     }
 100 
 101     // ByteArrayInputStream bais = new ByteArrayInputStream(buf);
 102     InstanceKlass* bais_klass = SystemDictionary::ByteArrayInputStream_klass();
 103     Handle bais = bais_klass->allocate_instance_handle(CHECK_(empty));
 104     {
 105       const char* src = ent->manifest();
 106       assert(src != NULL, "No Manifest data");
 107       typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_(empty));
 108       typeArrayHandle bufhandle(THREAD, buf);
 109       char* dst = (char*)(buf->byte_at_addr(0));
 110       memcpy(dst, src, (size_t)size);
 111 
 112       JavaValue result(T_VOID);
 113       JavaCalls::call_special(&result, bais, bais_klass,
 114                               vmSymbols::object_initializer_name(),
 115                               vmSymbols::byte_array_void_signature(),


 286 
 287       Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD);
 288       mod->set_shared_protection_domain(loader_data, pd);
 289     }
 290   }
 291 
 292   protection_domain = Handle(THREAD, mod->shared_protection_domain());
 293   assert(protection_domain.not_null(), "sanity");
 294   return protection_domain;
 295 }
 296 
 297 // Initializes the java.lang.Package and java.security.ProtectionDomain objects associated with
 298 // the given InstanceKlass.
 299 // Returns the ProtectionDomain for the InstanceKlass.
 300 Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS) {
 301   Handle pd;
 302 
 303   if (ik != NULL) {
 304     int index = ik->shared_classpath_index();
 305     assert(index >= 0, "Sanity");
 306     SharedClassPathEntryExt* ent =
 307             (SharedClassPathEntryExt*)FileMapInfo::shared_path(index);
 308     Symbol* class_name = ik->name();
 309 
 310     if (ent->is_modules_image()) {
 311       // For shared app/platform classes originated from the run-time image:
 312       //   The ProtectionDomains are cached in the corresponding ModuleEntries
 313       //   for fast access by the VM.
 314       ResourceMark rm;
 315       ClassLoaderData *loader_data =
 316                 ClassLoaderData::class_loader_data(class_loader());
 317       PackageEntryTable* pkgEntryTable = loader_data->packages();
 318       TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_(pd));
 319       if (pkg_name != NULL) {
 320         PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name);
 321         if (pkg_entry != NULL) {
 322           ModuleEntry* mod_entry = pkg_entry->module();
 323           pd = get_shared_protection_domain(class_loader, mod_entry, THREAD);
 324           define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd));
 325         }
 326       }
 327     } else {


 459           } else {
 460             assert(path_index < FileMapInfo::get_number_of_shared_paths(), "invalid path_index");
 461           }
 462         }
 463       }
 464     }
 465   } else {
 466     // TEMP: if a shared class can be found by a custom loader, consider it visible now.
 467     // FIXME: is this actually correct?
 468     return true;
 469   }
 470   return false;
 471 }
 472 
 473 // The following stack shows how this code is reached:
 474 //
 475 //   [0] SystemDictionaryShared::find_or_load_shared_class()
 476 //   [1] JVM_FindLoadedClass
 477 //   [2] java.lang.ClassLoader.findLoadedClass0()
 478 //   [3] java.lang.ClassLoader.findLoadedClass()
 479 //   [4] java.lang.ClassLoader.loadClass()
 480 //   [5] jdk.internal.loader.ClassLoaders$AppClassLoader_klass.loadClass()


 481 //
 482 // Because AppCDS supports only the PlatformClassLoader and AppClassLoader, we make the following
 483 // assumptions (based on the JDK 8.0 source code):


 484 //
 485 // [a] these two loaders use the default implementation of
 486 //     ClassLoader.loadClass(String name, boolean resolve), which
 487 // [b] calls findLoadedClass(name), immediately followed by parent.loadClass(),
 488 //     immediately followed by findClass(name).
 489 // [c] If the requested class is a shared class of the current class loader, parent.loadClass()
 490 //     always returns null, and
 491 // [d] if AppCDS is not enabled, the class would be loaded by findClass() by decoding it from a
 492 //     JAR file and then parsed.


 493 //
 494 // Given these assumptions, we intercept the findLoadedClass() call to invoke
 495 // SystemDictionaryShared::find_or_load_shared_class() to load the shared class from
 496 // the archive. The reasons are:
 497 //
 498 // + Because AppCDS is a commercial feature, we want to hide the implementation. There
 499 //   is currently no easy way to hide Java code, so we did it with native code.
 500 // + Start-up is improved because we avoid decoding the JAR file, and avoid delegating
 501 //   to the parent (since we know the parent will not find this class).
 502 //
 503 // NOTE: there's a lot of assumption about the Java code. If any of that change, this
 504 // needs to be redesigned.
 505 //
 506 // An alternative is to modify the Java code of AppClassLoader.loadClass().
 507 //
 508 InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
 509                  Symbol* name, Handle class_loader, TRAPS) {
 510   InstanceKlass* k = NULL;
 511   if (UseSharedSpaces) {
 512     FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
 513     if (!header->has_platform_or_app_classes()) {
 514       return NULL;
 515     }
 516 
 517     if (shared_dictionary() != NULL &&
 518         (SystemDictionary::is_system_class_loader(class_loader()) ||
 519          SystemDictionary::is_platform_class_loader(class_loader()))) {
 520       // Fix for 4474172; see evaluation for more details
 521       class_loader = Handle(
 522         THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
 523       ClassLoaderData *loader_data = register_loader(class_loader);
 524       Dictionary* dictionary = loader_data->dictionary();
 525 
 526       unsigned int d_hash = dictionary->compute_hash(name);
 527 
 528       bool DoObjectLock = true;
 529       if (is_parallelCapable(class_loader)) {
 530         DoObjectLock = false;
 531       }
 532 
 533       // Make sure we are synchronized on the class loader before we proceed




  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/classFileStream.hpp"
  27 #include "classfile/classListParser.hpp"
  28 #include "classfile/classLoader.hpp"
  29 #include "classfile/classLoaderData.inline.hpp"
  30 #include "classfile/classLoaderExt.hpp"
  31 #include "classfile/compactHashtable.inline.hpp"
  32 #include "classfile/dictionary.hpp"
  33 #include "classfile/javaClasses.hpp"

  34 #include "classfile/symbolTable.hpp"
  35 #include "classfile/systemDictionary.hpp"
  36 #include "classfile/systemDictionaryShared.hpp"
  37 #include "classfile/verificationType.hpp"
  38 #include "classfile/vmSymbols.hpp"
  39 #include "logging/log.hpp"
  40 #include "memory/allocation.hpp"
  41 #include "memory/filemap.hpp"
  42 #include "memory/metadataFactory.hpp"
  43 #include "memory/metaspaceClosure.hpp"
  44 #include "memory/oopFactory.hpp"
  45 #include "memory/resourceArea.hpp"
  46 #include "oops/instanceKlass.hpp"
  47 #include "oops/klass.inline.hpp"
  48 #include "oops/objArrayOop.inline.hpp"
  49 #include "oops/oop.inline.hpp"
  50 #include "oops/typeArrayOop.inline.hpp"
  51 #include "runtime/handles.inline.hpp"
  52 #include "runtime/java.hpp"
  53 #include "runtime/javaCalls.hpp"


  74   }
  75 }
  76 
  77 oop SystemDictionaryShared::shared_protection_domain(int index) {
  78   return _shared_protection_domains->obj_at(index);
  79 }
  80 
  81 oop SystemDictionaryShared::shared_jar_url(int index) {
  82   return _shared_jar_urls->obj_at(index);
  83 }
  84 
  85 oop SystemDictionaryShared::shared_jar_manifest(int index) {
  86   return _shared_jar_manifests->obj_at(index);
  87 }
  88 
  89 
  90 Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TRAPS) {
  91   Handle empty;
  92   Handle manifest ;
  93   if (shared_jar_manifest(shared_path_index) == NULL) {
  94     SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index);
  95     long size = ent->manifest_size();
  96     if (size <= 0) {
  97       return empty; // No manifest - return NULL handle
  98     }
  99 
 100     // ByteArrayInputStream bais = new ByteArrayInputStream(buf);
 101     InstanceKlass* bais_klass = SystemDictionary::ByteArrayInputStream_klass();
 102     Handle bais = bais_klass->allocate_instance_handle(CHECK_(empty));
 103     {
 104       const char* src = ent->manifest();
 105       assert(src != NULL, "No Manifest data");
 106       typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_(empty));
 107       typeArrayHandle bufhandle(THREAD, buf);
 108       char* dst = (char*)(buf->byte_at_addr(0));
 109       memcpy(dst, src, (size_t)size);
 110 
 111       JavaValue result(T_VOID);
 112       JavaCalls::call_special(&result, bais, bais_klass,
 113                               vmSymbols::object_initializer_name(),
 114                               vmSymbols::byte_array_void_signature(),


 285 
 286       Handle pd = get_protection_domain_from_classloader(class_loader, url, THREAD);
 287       mod->set_shared_protection_domain(loader_data, pd);
 288     }
 289   }
 290 
 291   protection_domain = Handle(THREAD, mod->shared_protection_domain());
 292   assert(protection_domain.not_null(), "sanity");
 293   return protection_domain;
 294 }
 295 
 296 // Initializes the java.lang.Package and java.security.ProtectionDomain objects associated with
 297 // the given InstanceKlass.
 298 // Returns the ProtectionDomain for the InstanceKlass.
 299 Handle SystemDictionaryShared::init_security_info(Handle class_loader, InstanceKlass* ik, TRAPS) {
 300   Handle pd;
 301 
 302   if (ik != NULL) {
 303     int index = ik->shared_classpath_index();
 304     assert(index >= 0, "Sanity");
 305     SharedClassPathEntry* ent = FileMapInfo::shared_path(index);

 306     Symbol* class_name = ik->name();
 307 
 308     if (ent->is_modules_image()) {
 309       // For shared app/platform classes originated from the run-time image:
 310       //   The ProtectionDomains are cached in the corresponding ModuleEntries
 311       //   for fast access by the VM.
 312       ResourceMark rm;
 313       ClassLoaderData *loader_data =
 314                 ClassLoaderData::class_loader_data(class_loader());
 315       PackageEntryTable* pkgEntryTable = loader_data->packages();
 316       TempNewSymbol pkg_name = InstanceKlass::package_from_name(class_name, CHECK_(pd));
 317       if (pkg_name != NULL) {
 318         PackageEntry* pkg_entry = pkgEntryTable->lookup_only(pkg_name);
 319         if (pkg_entry != NULL) {
 320           ModuleEntry* mod_entry = pkg_entry->module();
 321           pd = get_shared_protection_domain(class_loader, mod_entry, THREAD);
 322           define_shared_package(class_name, class_loader, mod_entry, CHECK_(pd));
 323         }
 324       }
 325     } else {


 457           } else {
 458             assert(path_index < FileMapInfo::get_number_of_shared_paths(), "invalid path_index");
 459           }
 460         }
 461       }
 462     }
 463   } else {
 464     // TEMP: if a shared class can be found by a custom loader, consider it visible now.
 465     // FIXME: is this actually correct?
 466     return true;
 467   }
 468   return false;
 469 }
 470 
 471 // The following stack shows how this code is reached:
 472 //
 473 //   [0] SystemDictionaryShared::find_or_load_shared_class()
 474 //   [1] JVM_FindLoadedClass
 475 //   [2] java.lang.ClassLoader.findLoadedClass0()
 476 //   [3] java.lang.ClassLoader.findLoadedClass()
 477 //   [4] jdk.internal.loader.BuiltinClassLoader.loadClassOrNull()
 478 //   [5] jdk.internal.loader.BuiltinClassLoader.loadClass()
 479 //   [6] jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(), or
 480 //       jdk.internal.loader.ClassLoaders$PlatformClassLoader.loadClass()
 481 //
 482 // AppCDS supports fast class loading for these 2 built-in class loaders:
 483 //    jdk.internal.loader.ClassLoaders$PlatformClassLoader
 484 //    jdk.internal.loader.ClassLoaders$AppClassLoader
 485 // with the following assumptions (based on the JDK core library source code):
 486 //
 487 // [a] these two loaders use the BuiltinClassLoader.loadClassOrNull() to
 488 //     load the named class.
 489 // [b] BuiltinClassLoader.loadClassOrNull() first calls findLoadedClass(name).
 490 // [c] At this point, if the named class was loaded by the
 491 //     AppClassLoader during archive dump time, we know that it must be
 492 //     loaded by the AppClassLoader during run time, and will not be loaded
 493 //     by a delegated class loader. This is true because we have checked the
 494 //     CLASSPATH and module path to ensure compatibility between dump time and
 495 //     run time.
 496 //     (The above paragraph is also true for the PlatformClassLoader).
 497 //
 498 // Given these assumptions, we intercept the findLoadedClass() call to invoke
 499 // SystemDictionaryShared::find_or_load_shared_class() to load the shared class from
 500 // the archive (subject to checks inside is_shared_class_visible_for_classloader()).
 501 // This allows us to improve start-up because we avoid decoding the classfile,
 502 // and avoid delegating to the parent loader (since we know the parent will not find
 503 // this class).


 504 //
 505 // NOTE: there's a lot of assumption about the Java code. If any of that change, this
 506 // needs to be redesigned.
 507 //
 508 // An alternative is to modify the Java code of BuiltinClassLoader.loadClassOrNull().
 509 //
 510 InstanceKlass* SystemDictionaryShared::find_or_load_shared_class(
 511                  Symbol* name, Handle class_loader, TRAPS) {
 512   InstanceKlass* k = NULL;
 513   if (UseSharedSpaces) {
 514     if (!FileMapInfo::current_info()->header()->has_platform_or_app_classes()) {

 515       return NULL;
 516     }
 517 
 518     if (shared_dictionary() != NULL &&
 519         (SystemDictionary::is_system_class_loader(class_loader()) ||
 520          SystemDictionary::is_platform_class_loader(class_loader()))) {
 521       // Fix for 4474172; see evaluation for more details
 522       class_loader = Handle(
 523         THREAD, java_lang_ClassLoader::non_reflection_class_loader(class_loader()));
 524       ClassLoaderData *loader_data = register_loader(class_loader);
 525       Dictionary* dictionary = loader_data->dictionary();
 526 
 527       unsigned int d_hash = dictionary->compute_hash(name);
 528 
 529       bool DoObjectLock = true;
 530       if (is_parallelCapable(class_loader)) {
 531         DoObjectLock = false;
 532       }
 533 
 534       // Make sure we are synchronized on the class loader before we proceed


< prev index next >