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
|