145 GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL; |
145 GrowableArray<ModuleClassPathList*>* ClassLoader::_exploded_entries = NULL; |
146 ClassPathEntry* ClassLoader::_jrt_entry = NULL; |
146 ClassPathEntry* ClassLoader::_jrt_entry = NULL; |
147 ClassPathEntry* ClassLoader::_first_append_entry = NULL; |
147 ClassPathEntry* ClassLoader::_first_append_entry = NULL; |
148 ClassPathEntry* ClassLoader::_last_append_entry = NULL; |
148 ClassPathEntry* ClassLoader::_last_append_entry = NULL; |
149 int ClassLoader::_num_entries = 0; |
149 int ClassLoader::_num_entries = 0; |
|
150 int ClassLoader::_num_boot_entries = -1; |
150 #if INCLUDE_CDS |
151 #if INCLUDE_CDS |
151 GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL; |
152 GrowableArray<char*>* ClassLoader::_boot_modules_array = NULL; |
152 GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL; |
153 GrowableArray<char*>* ClassLoader::_platform_modules_array = NULL; |
153 SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL; |
154 SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL; |
154 #endif |
155 #endif |
240 return (const char *)pkg_name; |
241 return (const char *)pkg_name; |
241 } |
242 } |
242 |
243 |
243 // Given a fully qualified class name, find its defining package in the class loader's |
244 // Given a fully qualified class name, find its defining package in the class loader's |
244 // package entry table. |
245 // package entry table. |
245 static PackageEntry* get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) { |
246 PackageEntry* ClassLoader::get_package_entry(const char* class_name, ClassLoaderData* loader_data, TRAPS) { |
246 ResourceMark rm(THREAD); |
247 ResourceMark rm(THREAD); |
247 const char *pkg_name = ClassLoader::package_from_name(class_name); |
248 const char *pkg_name = ClassLoader::package_from_name(class_name); |
248 if (pkg_name == NULL) { |
249 if (pkg_name == NULL) { |
249 return NULL; |
250 return NULL; |
250 } |
251 } |
536 _name, |
537 _name, |
537 ClassFileStream::verify); |
538 ClassFileStream::verify); |
538 } |
539 } |
539 |
540 |
540 return NULL; |
541 return NULL; |
|
542 } |
|
543 |
|
544 JImageLocationRef ClassLoader::jimage_find_resource(JImageFile* jf, |
|
545 const char* module_name, |
|
546 const char* file_name, |
|
547 jlong &size) { |
|
548 return ((*JImageFindResource)(jf, module_name, get_jimage_version_string(), file_name, &size)); |
541 } |
549 } |
542 |
550 |
543 #ifndef PRODUCT |
551 #ifndef PRODUCT |
544 bool ctw_visitor(JImageFile* jimage, |
552 bool ctw_visitor(JImageFile* jimage, |
545 const char* module_name, const char* version, const char* package, |
553 const char* module_name, const char* version, const char* package, |
1457 // If both DumpSharedSpaces and search_append_only are false, boot loader |
1465 // If both DumpSharedSpaces and search_append_only are false, boot loader |
1458 // visibility boundaries are set to be the --patch-module entries plus the base piece. |
1466 // visibility boundaries are set to be the --patch-module entries plus the base piece. |
1459 // This would include: |
1467 // This would include: |
1460 // [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build] |
1468 // [--patch-module=<module>=<file>(<pathsep><file>)*]; [jimage | exploded module build] |
1461 // |
1469 // |
1462 // DumpSharedSpaces and search_append_only are mutually exclusive and cannot |
|
1463 // be true at the same time. |
|
1464 assert(!(DumpSharedSpaces && search_append_only), "DumpSharedSpaces and search_append_only are both true"); |
|
1465 |
1470 |
1466 // Load Attempt #1: --patch-module |
1471 // Load Attempt #1: --patch-module |
1467 // Determine the class' defining module. If it appears in the _patch_mod_entries, |
1472 // Determine the class' defining module. If it appears in the _patch_mod_entries, |
1468 // attempt to load the class from those locations specific to the module. |
1473 // attempt to load the class from those locations specific to the module. |
1469 // Specifications to --patch-module can contain a partial number of classes |
1474 // Specifications to --patch-module can contain a partial number of classes |
1505 assert(classpath_index == 0, "The classpath_index has been incremented incorrectly"); |
1510 assert(classpath_index == 0, "The classpath_index has been incremented incorrectly"); |
1506 classpath_index = 1; |
1511 classpath_index = 1; |
1507 |
1512 |
1508 e = _first_append_entry; |
1513 e = _first_append_entry; |
1509 while (e != NULL) { |
1514 while (e != NULL) { |
|
1515 if (DumpSharedSpaces && classpath_index >= _num_boot_entries) { |
|
1516 // Do not load any class from the app classpath using the boot loader. Let |
|
1517 // the built-in app class laoder load them. |
|
1518 break; |
|
1519 } |
1510 stream = e->open_stream(file_name, CHECK_NULL); |
1520 stream = e->open_stream(file_name, CHECK_NULL); |
1511 if (!context.check(stream, classpath_index)) { |
1521 if (!context.check(stream, classpath_index)) { |
1512 return NULL; |
1522 return NULL; |
1513 } |
1523 } |
1514 if (NULL != stream) { |
1524 if (NULL != stream) { |
1545 return NULL; |
1552 return NULL; |
1546 } |
1553 } |
1547 |
1554 |
1548 return context.record_result(name, e, classpath_index, result, THREAD); |
1555 return context.record_result(name, e, classpath_index, result, THREAD); |
1549 } |
1556 } |
|
1557 |
|
1558 #if INCLUDE_CDS |
|
1559 static char* skip_uri_protocol(char* source) { |
|
1560 if (strncmp(source, "file:", 5) == 0) { |
|
1561 // file: protocol path could start with file:/ or file:/// |
|
1562 // locate the char after all the forward slashes |
|
1563 int offset = 5; |
|
1564 while (*(source + offset) == '/') { |
|
1565 offset++; |
|
1566 } |
|
1567 source += offset; |
|
1568 // for non-windows platforms, move back one char as the path begins with a '/' |
|
1569 #ifndef _WINDOWS |
|
1570 source -= 1; |
|
1571 #endif |
|
1572 } else if (strncmp(source, "jrt:/", 5) == 0) { |
|
1573 source += 5; |
|
1574 } |
|
1575 return source; |
|
1576 } |
|
1577 |
|
1578 void ClassLoader::record_shared_class_loader_type(InstanceKlass* ik, const ClassFileStream* stream) { |
|
1579 assert(DumpSharedSpaces, "sanity"); |
|
1580 assert(stream != NULL, "sanity"); |
|
1581 |
|
1582 if (ik->is_anonymous()) { |
|
1583 // We do not archive anonymous classes. |
|
1584 return; |
|
1585 } |
|
1586 |
|
1587 if (stream->source() == NULL) { |
|
1588 if (ik->class_loader() == NULL) { |
|
1589 // JFR classes |
|
1590 ik->set_shared_classpath_index(0); |
|
1591 ik->set_class_loader_type(ClassLoader::BOOT_LOADER); |
|
1592 } |
|
1593 return; |
|
1594 } |
|
1595 |
|
1596 assert(has_jrt_entry(), "CDS dumping does not support exploded JDK build"); |
|
1597 |
|
1598 ModuleEntry* module = ik->module(); |
|
1599 ClassPathEntry* e = NULL; |
|
1600 int classpath_index = 0; |
|
1601 |
|
1602 // Check if the class is from the runtime image |
|
1603 if (module != NULL && (module->location() != NULL) && |
|
1604 (module->location()->starts_with("jrt:"))) { |
|
1605 e = _jrt_entry; |
|
1606 classpath_index = 0; |
|
1607 } else { |
|
1608 classpath_index = 1; |
|
1609 ResourceMark rm; |
|
1610 char* canonical_path = NEW_RESOURCE_ARRAY(char, JVM_MAXPATHLEN); |
|
1611 for (e = _first_append_entry; e != NULL; e = e->next()) { |
|
1612 if (get_canonical_path(e->name(), canonical_path, JVM_MAXPATHLEN)) { |
|
1613 char* src = (char*)stream->source(); |
|
1614 // save the path from the file: protocol or the module name from the jrt: protocol |
|
1615 // if no protocol prefix is found, src is the same as stream->source() after the following call |
|
1616 src = skip_uri_protocol(src); |
|
1617 if (strcmp(canonical_path, os::native_path((char*)src)) == 0) { |
|
1618 break; |
|
1619 } |
|
1620 classpath_index ++; |
|
1621 } |
|
1622 } |
|
1623 if (e == NULL) { |
|
1624 assert(ik->shared_classpath_index() < 0, |
|
1625 "must be a class from a custom jar which isn't in the class path or boot class path"); |
|
1626 return; |
|
1627 } |
|
1628 } |
|
1629 |
|
1630 if (classpath_index < _num_boot_entries) { |
|
1631 // ik is either: |
|
1632 // 1) a boot class loaded from the runtime image during vm initialization (classpath_index = 0); or |
|
1633 // 2) a user's class from -Xbootclasspath/a (classpath_index > 0) |
|
1634 // In the second case, the classpath_index, classloader_type will be recorded via |
|
1635 // context.record_result() in ClassLoader::load_class(Symbol* name, bool search_append_only, TRAPS). |
|
1636 if (classpath_index > 0) { |
|
1637 return; |
|
1638 } |
|
1639 } |
|
1640 |
|
1641 ResourceMark rm; |
|
1642 const char* const class_name = ik->name()->as_C_string(); |
|
1643 const char* const file_name = file_name_for_class_name(class_name, |
|
1644 ik->name()->utf8_length()); |
|
1645 assert(file_name != NULL, "invariant"); |
|
1646 Thread* THREAD = Thread::current(); |
|
1647 ClassLoaderExt::Context context(class_name, file_name, CATCH); |
|
1648 context.record_result(ik->name(), e, classpath_index, ik, THREAD); |
|
1649 } |
|
1650 #endif // INCLUDE_CDS |
1550 |
1651 |
1551 // Initialize the class loader's access to methods in libzip. Parse and |
1652 // Initialize the class loader's access to methods in libzip. Parse and |
1552 // process the boot classpath into a list ClassPathEntry objects. Once |
1653 // process the boot classpath into a list ClassPathEntry objects. Once |
1553 // this list has been created, it must not change order (see class PackageInfo) |
1654 // this list has been created, it must not change order (see class PackageInfo) |
1554 // it can be appended to and is by jvmti and the kernel vm. |
1655 // it can be appended to and is by jvmti and the kernel vm. |