mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-25 05:45:11 +02:00
8049367: Modular Run-Time Images
Co-authored-by: Alan Bateman <alan.bateman@oracle.com> Co-authored-by: Alex Buckley <alex.buckley@oracle.com> Co-authored-by: Bradford Wetmore <bradford.wetmore@oracle.com> Co-authored-by: Erik Joelsson <erik.joelsson@oracle.com> Co-authored-by: James Laskey <james.laskey@oracle.com> Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com> Co-authored-by: Karen Kinnear <karen.kinnear@oracle.com> Co-authored-by: Magnus Ihse Bursie <magnus.ihse.bursie@oracle.com> Co-authored-by: Mandy Chung <mandy.chung@oracle.com> Co-authored-by: Mark Reinhold <mark.reinhold@oracle.com> Co-authored-by: Paul Sandoz <paul.sandoz@oracle.com> Co-authored-by: Sundararajan Athijegannathan <sundararajan.athijegannathan@oracle.com> Reviewed-by: chegar, dfuchs, ihse, joehw, mullan, psandoz, wetmore
This commit is contained in:
parent
785151164a
commit
393a39afe3
19 changed files with 944 additions and 146 deletions
|
@ -28,6 +28,7 @@
|
|||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoaderExt.hpp"
|
||||
#include "classfile/classLoaderData.inline.hpp"
|
||||
#include "classfile/imageFile.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#if INCLUDE_CDS
|
||||
#include "classfile/sharedPathsMiscInfo.hpp"
|
||||
|
@ -67,7 +68,7 @@
|
|||
#include "utilities/hashtable.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
|
||||
// Entry points in zip.dll for loading zip/jar file entries
|
||||
// Entry points in zip.dll for loading zip/jar file entries and image file entries
|
||||
|
||||
typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg);
|
||||
typedef void (JNICALL *ZipClose_t)(jzfile *zip);
|
||||
|
@ -75,6 +76,7 @@ typedef jzentry* (JNICALL *FindEntry_t)(jzfile *zip, const char *name, jint *siz
|
|||
typedef jboolean (JNICALL *ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf);
|
||||
typedef jboolean (JNICALL *ReadMappedEntry_t)(jzfile *zip, jzentry *entry, unsigned char **buf, char *namebuf);
|
||||
typedef jzentry* (JNICALL *GetNextEntry_t)(jzfile *zip, jint n);
|
||||
typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
|
||||
typedef jint (JNICALL *Crc32_t)(jint crc, const jbyte *buf, jint len);
|
||||
|
||||
static ZipOpen_t ZipOpen = NULL;
|
||||
|
@ -84,6 +86,7 @@ static ReadEntry_t ReadEntry = NULL;
|
|||
static ReadMappedEntry_t ReadMappedEntry = NULL;
|
||||
static GetNextEntry_t GetNextEntry = NULL;
|
||||
static canonicalize_fn_t CanonicalizeEntry = NULL;
|
||||
static ZipInflateFully_t ZipInflateFully = NULL;
|
||||
static Crc32_t Crc32 = NULL;
|
||||
|
||||
// Globals
|
||||
|
@ -322,6 +325,8 @@ LazyClassPathEntry::~LazyClassPathEntry() {
|
|||
}
|
||||
|
||||
bool LazyClassPathEntry::is_jar_file() {
|
||||
size_t len = strlen(_path);
|
||||
if (len < 4 || strcmp(_path + len - 4, ".jar") != 0) return false;
|
||||
return ((_st.st_mode & S_IFREG) == S_IFREG);
|
||||
}
|
||||
|
||||
|
@ -385,6 +390,78 @@ u1* LazyClassPathEntry::open_entry(const char* name, jint* filesize, bool nul_te
|
|||
}
|
||||
}
|
||||
|
||||
ClassPathImageEntry::ClassPathImageEntry(char* name) : ClassPathEntry(), _image(new ImageFile(name)) {
|
||||
bool opened = _image->open();
|
||||
if (!opened) {
|
||||
_image = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ClassPathImageEntry::~ClassPathImageEntry() {
|
||||
if (_image) {
|
||||
_image->close();
|
||||
_image = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char* ClassPathImageEntry::name() {
|
||||
return _image ? _image->name() : "";
|
||||
}
|
||||
|
||||
ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) {
|
||||
u1* buffer;
|
||||
u8 size;
|
||||
_image->get_resource(name, buffer, size);
|
||||
|
||||
if (buffer) {
|
||||
if (UsePerfData) {
|
||||
ClassLoader::perf_sys_classfile_bytes_read()->inc(size);
|
||||
}
|
||||
return new ClassFileStream(buffer, (int)size, (char*)name); // Resource allocated
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
void ClassPathImageEntry::compile_the_world(Handle loader, TRAPS) {
|
||||
tty->print_cr("CompileTheWorld : Compiling all classes in %s", name());
|
||||
tty->cr();
|
||||
const ImageStrings strings = _image->get_strings();
|
||||
// Retrieve each path component string.
|
||||
u4 count = _image->get_location_count();
|
||||
for (u4 i = 0; i < count; i++) {
|
||||
u1* location_data = _image->get_location_data(i);
|
||||
|
||||
if (location_data) {
|
||||
ImageLocation location(location_data);
|
||||
const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
|
||||
const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
|
||||
const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
|
||||
assert((strlen(parent) + strlen(base) + strlen(extension)) < JVM_MAXPATHLEN, "path exceeds buffer");
|
||||
char path[JVM_MAXPATHLEN];
|
||||
strcpy(path, parent);
|
||||
strcat(path, base);
|
||||
strcat(path, extension);
|
||||
ClassLoader::compile_the_world_in(path, loader, CHECK);
|
||||
}
|
||||
}
|
||||
if (HAS_PENDING_EXCEPTION) {
|
||||
if (PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())) {
|
||||
CLEAR_PENDING_EXCEPTION;
|
||||
tty->print_cr("\nCompileTheWorld : Ran out of memory\n");
|
||||
tty->print_cr("Increase class metadata storage if a limit was set");
|
||||
} else {
|
||||
tty->print_cr("\nCompileTheWorld : Unexpected exception occurred\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ClassPathImageEntry::is_jrt() {
|
||||
return string_ends_with(name(), "bootmodules.jimage");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void print_meta_index(LazyClassPathEntry* entry,
|
||||
GrowableArray<char*>& meta_packages) {
|
||||
tty->print("[Meta index for %s=", entry->name());
|
||||
|
@ -634,7 +711,7 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
|
|||
}
|
||||
ClassPathEntry* new_entry = NULL;
|
||||
if ((st->st_mode & S_IFREG) == S_IFREG) {
|
||||
// Regular file, should be a zip file
|
||||
// Regular file, should be a zip or image file
|
||||
// Canonicalized filename
|
||||
char canonical_path[JVM_MAXPATHLEN];
|
||||
if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) {
|
||||
|
@ -645,6 +722,11 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
// TODO - add proper criteria for selecting image file
|
||||
ClassPathImageEntry* entry = new ClassPathImageEntry(canonical_path);
|
||||
if (entry->is_open()) {
|
||||
new_entry = entry;
|
||||
} else {
|
||||
char* error_msg = NULL;
|
||||
jzfile* zip;
|
||||
{
|
||||
|
@ -655,9 +737,6 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
|
|||
}
|
||||
if (zip != NULL && error_msg == NULL) {
|
||||
new_entry = new ClassPathZipEntry(zip, path);
|
||||
if (TraceClassLoading || TraceClassPaths) {
|
||||
tty->print_cr("[Opened %s]", path);
|
||||
}
|
||||
} else {
|
||||
ResourceMark rm(thread);
|
||||
char *msg;
|
||||
|
@ -675,10 +754,14 @@ ClassPathEntry* ClassLoader::create_class_path_entry(const char *path, const str
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (TraceClassLoading || TraceClassPaths) {
|
||||
tty->print_cr("[Opened %s]", path);
|
||||
}
|
||||
} else {
|
||||
// Directory
|
||||
new_entry = new ClassPathDirEntry(path);
|
||||
if (TraceClassLoading || TraceClassPaths) {
|
||||
if (TraceClassLoading) {
|
||||
tty->print_cr("[Path %s]", path);
|
||||
}
|
||||
}
|
||||
|
@ -801,6 +884,7 @@ void ClassLoader::load_zip_library() {
|
|||
ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, os::dll_lookup(handle, "ZIP_ReadEntry"));
|
||||
ReadMappedEntry = CAST_TO_FN_PTR(ReadMappedEntry_t, os::dll_lookup(handle, "ZIP_ReadMappedEntry"));
|
||||
GetNextEntry = CAST_TO_FN_PTR(GetNextEntry_t, os::dll_lookup(handle, "ZIP_GetNextEntry"));
|
||||
ZipInflateFully = CAST_TO_FN_PTR(ZipInflateFully_t, os::dll_lookup(handle, "ZIP_InflateFully"));
|
||||
Crc32 = CAST_TO_FN_PTR(Crc32_t, os::dll_lookup(handle, "ZIP_CRC32"));
|
||||
|
||||
// ZIP_Close is not exported on Windows in JDK5.0 so don't abort if ZIP_Close is NULL
|
||||
|
@ -809,12 +893,20 @@ void ClassLoader::load_zip_library() {
|
|||
vm_exit_during_initialization("Corrupted ZIP library", path);
|
||||
}
|
||||
|
||||
if (ZipInflateFully == NULL) {
|
||||
vm_exit_during_initialization("Corrupted ZIP library ZIP_InflateFully missing", path);
|
||||
}
|
||||
|
||||
// Lookup canonicalize entry in libjava.dll
|
||||
void *javalib_handle = os::native_java_library();
|
||||
CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, os::dll_lookup(javalib_handle, "Canonicalize"));
|
||||
// This lookup only works on 1.3. Do not check for non-null here
|
||||
}
|
||||
|
||||
jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
|
||||
return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
|
||||
}
|
||||
|
||||
int ClassLoader::crc32(int crc, const char* buf, int len) {
|
||||
assert(Crc32 != NULL, "ZIP_CRC32 is not found");
|
||||
return (*Crc32)(crc, (const jbyte*)buf, len);
|
||||
|
@ -1367,8 +1459,7 @@ void ClassPathDirEntry::compile_the_world(Handle loader, TRAPS) {
|
|||
tty->cr();
|
||||
}
|
||||
|
||||
|
||||
bool ClassPathDirEntry::is_rt_jar() {
|
||||
bool ClassPathDirEntry::is_jrt() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1393,13 +1484,13 @@ void ClassPathZipEntry::compile_the_world(Handle loader, TRAPS) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ClassPathZipEntry::is_rt_jar() {
|
||||
bool ClassPathZipEntry::is_jrt() {
|
||||
real_jzfile* zip = (real_jzfile*) _zip;
|
||||
int len = (int)strlen(zip->name);
|
||||
// Check whether zip name ends in "rt.jar"
|
||||
// This will match other archives named rt.jar as well, but this is
|
||||
// only used for debugging.
|
||||
return (len >= 6) && (strcasecmp(zip->name + len - 6, "rt.jar") == 0);
|
||||
return string_ends_with(zip->name, "rt.jar");
|
||||
}
|
||||
|
||||
void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
|
||||
|
@ -1409,7 +1500,7 @@ void LazyClassPathEntry::compile_the_world(Handle loader, TRAPS) {
|
|||
}
|
||||
}
|
||||
|
||||
bool LazyClassPathEntry::is_rt_jar() {
|
||||
bool LazyClassPathEntry::is_jrt() {
|
||||
Thread* THREAD = Thread::current();
|
||||
ClassPathEntry* cpe = resolve_entry(THREAD);
|
||||
return (cpe != NULL) ? cpe->is_jar_file() : false;
|
||||
|
@ -1428,7 +1519,7 @@ void ClassLoader::compile_the_world() {
|
|||
jlong start = os::javaTimeMillis();
|
||||
while (e != NULL) {
|
||||
// We stop at rt.jar, unless it is the first bootstrap path entry
|
||||
if (e->is_rt_jar() && e != _first_entry) break;
|
||||
if (e->is_jrt() && e != _first_entry) break;
|
||||
e->compile_the_world(system_class_loader, CATCH);
|
||||
e = e->next();
|
||||
}
|
||||
|
@ -1476,9 +1567,9 @@ static bool can_be_compiled(methodHandle m, int comp_level) {
|
|||
}
|
||||
|
||||
void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
|
||||
int len = (int)strlen(name);
|
||||
if (len > 6 && strcmp(".class", name + len - 6) == 0) {
|
||||
if (string_ends_with(name, ".class")) {
|
||||
// We have a .class file
|
||||
int len = (int)strlen(name);
|
||||
char buffer[2048];
|
||||
strncpy(buffer, name, len - 6);
|
||||
buffer[len-6] = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue