diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index e3e85a150f0..205508eebec 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -86,22 +86,6 @@ typedef int (*canonicalize_fn_t)(const char *orig, char *out, int len); static canonicalize_fn_t CanonicalizeEntry = nullptr; -// Entry points in zip.dll for loading zip/jar file entries - -typedef void * * (*ZipOpen_t)(const char *name, char **pmsg); -typedef void (*ZipClose_t)(jzfile *zip); -typedef jzentry* (*FindEntry_t)(jzfile *zip, const char *name, jint *sizeP, jint *nameLen); -typedef jboolean (*ReadEntry_t)(jzfile *zip, jzentry *entry, unsigned char *buf, char *namebuf); -typedef jint (*Crc32_t)(jint crc, const jbyte *buf, jint len); - -static ZipOpen_t ZipOpen = nullptr; -static ZipClose_t ZipClose = nullptr; -static FindEntry_t FindEntry = nullptr; -static ReadEntry_t ReadEntry = nullptr; -static Crc32_t Crc32 = nullptr; -int ClassLoader::_libzip_loaded = 0; -void* ClassLoader::_zip_handle = nullptr; - // Entry points for jimage.dll for loading jimage file entries static JImageOpen_t JImageOpen = nullptr; @@ -292,7 +276,7 @@ ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name, } ClassPathZipEntry::~ClassPathZipEntry() { - (*ZipClose)(_zip); + ZipLibrary::close(_zip); FREE_C_HEAP_ARRAY(char, _zip_name); } @@ -301,7 +285,7 @@ u1* ClassPathZipEntry::open_entry(JavaThread* current, const char* name, jint* f ThreadToNativeFromVM ttn(current); // check whether zip archive contains name jint name_len; - jzentry* entry = (*FindEntry)(_zip, name, filesize, &name_len); + jzentry* entry = ZipLibrary::find_entry(_zip, name, filesize, &name_len); if (entry == nullptr) return nullptr; u1* buffer; char name_buf[128]; @@ -321,7 +305,9 @@ u1* ClassPathZipEntry::open_entry(JavaThread* current, const char* name, jint* f size++; } buffer = NEW_RESOURCE_ARRAY(u1, size); - if (!(*ReadEntry)(_zip, entry, buffer, filename)) return nullptr; + if (!ZipLibrary::read_entry(_zip, entry, buffer, filename)) { + return nullptr; + } // return result if (nul_terminate) { @@ -724,8 +710,7 @@ jzfile* ClassLoader::open_zip_file(const char* canonical_path, char** error_msg, // enable call to C land ThreadToNativeFromVM ttn(thread); HandleMark hm(thread); - load_zip_library_if_needed(); - return (*ZipOpen)(canonical_path, error_msg); + return ZipLibrary::open(canonical_path, error_msg); } ClassPathEntry* ClassLoader::create_class_path_entry(JavaThread* current, @@ -937,32 +922,6 @@ void ClassLoader::load_java_library() { CanonicalizeEntry = CAST_TO_FN_PTR(canonicalize_fn_t, dll_lookup(javalib_handle, "JDK_Canonicalize", nullptr)); } -void ClassLoader::release_load_zip_library() { - ConditionalMutexLocker locker(Zip_lock, Zip_lock != nullptr, Monitor::_no_safepoint_check_flag); - if (_libzip_loaded == 0) { - load_zip_library(); - Atomic::release_store(&_libzip_loaded, 1); - } -} - -void ClassLoader::load_zip_library() { - assert(ZipOpen == nullptr, "should not load zip library twice"); - char path[JVM_MAXPATHLEN]; - char ebuf[1024]; - if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { - _zip_handle = os::dll_load(path, ebuf, sizeof ebuf); - } - if (_zip_handle == nullptr) { - vm_exit_during_initialization("Unable to load zip library", path); - } - - ZipOpen = CAST_TO_FN_PTR(ZipOpen_t, dll_lookup(_zip_handle, "ZIP_Open", path)); - ZipClose = CAST_TO_FN_PTR(ZipClose_t, dll_lookup(_zip_handle, "ZIP_Close", path)); - FindEntry = CAST_TO_FN_PTR(FindEntry_t, dll_lookup(_zip_handle, "ZIP_FindEntry", path)); - ReadEntry = CAST_TO_FN_PTR(ReadEntry_t, dll_lookup(_zip_handle, "ZIP_ReadEntry", path)); - Crc32 = CAST_TO_FN_PTR(Crc32_t, dll_lookup(_zip_handle, "ZIP_CRC32", path)); -} - void ClassLoader::load_jimage_library() { assert(JImageOpen == nullptr, "should not load jimage library twice"); char path[JVM_MAXPATHLEN]; @@ -982,8 +941,7 @@ void ClassLoader::load_jimage_library() { } int ClassLoader::crc32(int crc, const char* buf, int len) { - load_zip_library_if_needed(); - return (*Crc32)(crc, (const jbyte*)buf, len); + return ZipLibrary::crc32(crc, (const jbyte*)buf, len); } oop ClassLoader::get_system_package(const char* name, TRAPS) { diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index 4cb1967194a..10373dbcf9f 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -30,6 +30,7 @@ #include "runtime/perfDataTypes.hpp" #include "utilities/exceptions.hpp" #include "utilities/macros.hpp" +#include "utilities/zipLibrary.hpp" // The VM class loader. #include @@ -84,19 +85,6 @@ class ClassPathDirEntry: public ClassPathEntry { ClassFileStream* open_stream(JavaThread* current, const char* name); }; -// Type definitions for zip file and zip file entry -typedef void* jzfile; -typedef struct { - char *name; /* entry name */ - jlong time; /* modification time */ - jlong size; /* size of uncompressed data */ - jlong csize; /* size of compressed data (zero if uncompressed) */ - jint crc; /* crc of uncompressed data */ - char *comment; /* optional zip file comment */ - jbyte *extra; /* optional extra data */ - jlong pos; /* position of LOC header (if negative) or data */ -} jzentry; - class ClassPathZipEntry: public ClassPathEntry { private: jzfile* _zip; // The zip archive @@ -227,8 +215,6 @@ class ClassLoader: AllStatic { CDS_ONLY(static void add_to_module_path_entries(const char* path, ClassPathEntry* entry);) - // cache the zip library handle - static void* _zip_handle; public: CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;}) CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;}) @@ -247,16 +233,10 @@ class ClassLoader: AllStatic { static void* dll_lookup(void* lib, const char* name, const char* path); static void load_java_library(); - static void load_zip_library(); static void load_jimage_library(); - private: - static int _libzip_loaded; // used to sync loading zip. - static void release_load_zip_library(); - public: - static inline void load_zip_library_if_needed(); - static void* zip_library_handle() { return _zip_handle; } + static void* zip_library_handle(); static jzfile* open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread); static ClassPathEntry* create_class_path_entry(JavaThread* current, const char *path, const struct stat* st, diff --git a/src/hotspot/share/classfile/classLoader.inline.hpp b/src/hotspot/share/classfile/classLoader.inline.hpp index e0a06880dd4..7f158a4c854 100644 --- a/src/hotspot/share/classfile/classLoader.inline.hpp +++ b/src/hotspot/share/classfile/classLoader.inline.hpp @@ -58,12 +58,6 @@ inline ClassPathEntry* ClassLoader::classpath_entry(int n) { } } -inline void ClassLoader::load_zip_library_if_needed() { - if (Atomic::load_acquire(&_libzip_loaded) == 0) { - release_load_zip_library(); - } -} - #if INCLUDE_CDS // Helper function used by CDS code to get the number of boot classpath diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 582eab9dc5b..d802d0bcfc7 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -103,6 +103,7 @@ #include "utilities/events.hpp" #include "utilities/macros.hpp" #include "utilities/utf8.hpp" +#include "utilities/zipLibrary.hpp" #if INCLUDE_CDS #include "classfile/systemDictionaryShared.hpp" #endif @@ -3413,8 +3414,7 @@ JVM_END // Library support /////////////////////////////////////////////////////////////////////////// JVM_LEAF(void*, JVM_LoadZipLibrary()) - ClassLoader::load_zip_library_if_needed(); - return ClassLoader::zip_library_handle(); + return ZipLibrary::handle(); JVM_END JVM_ENTRY_NO_ENV(void*, JVM_LoadLibrary(const char* name, jboolean throwException)) diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index 4a3444d9cae..62a685736c2 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -115,7 +115,6 @@ Monitor* Notification_lock = nullptr; Monitor* PeriodicTask_lock = nullptr; Monitor* RedefineClasses_lock = nullptr; Mutex* Verify_lock = nullptr; -Monitor* Zip_lock = nullptr; #if INCLUDE_JFR Mutex* JfrStacktrace_lock = nullptr; @@ -324,7 +323,6 @@ void mutex_init() { MUTEX_DEFN(ScratchObjects_lock , PaddedMutex , nosafepoint-1); // Holds DumpTimeTable_lock #endif // INCLUDE_CDS MUTEX_DEFN(Bootclasspath_lock , PaddedMutex , nosafepoint); - MUTEX_DEFN(Zip_lock , PaddedMonitor, nosafepoint-1); // Holds DumpTimeTable_lock #if INCLUDE_JVMCI // JVMCIRuntime::_lock must be acquired before JVMCI_lock to avoid deadlock diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 3bce342c251..9a0f9b9ab1e 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -111,7 +111,6 @@ extern Monitor* Notification_lock; // a lock used for notification extern Monitor* PeriodicTask_lock; // protects the periodic task structure extern Monitor* RedefineClasses_lock; // locks classes from parallel redefinition extern Mutex* Verify_lock; // synchronize initialization of verify library -extern Monitor* Zip_lock; // synchronize initialization of zip library extern Monitor* ThreadsSMRDelete_lock; // Used by ThreadsSMRSupport to take pressure off the Threads_lock extern Mutex* ThreadIdTableCreate_lock; // Used by ThreadIdTable to lazily create the thread id table extern Mutex* SharedDecoder_lock; // serializes access to the decoder during normal (not error reporting) use diff --git a/src/hotspot/share/services/heapDumperCompression.cpp b/src/hotspot/share/services/heapDumperCompression.cpp index d9a845d0ec7..b43f44becf3 100644 --- a/src/hotspot/share/services/heapDumperCompression.cpp +++ b/src/hotspot/share/services/heapDumperCompression.cpp @@ -25,11 +25,9 @@ #include "precompiled.hpp" #include "jvm.h" -#include "runtime/arguments.hpp" -#include "runtime/javaThread.hpp" -#include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "services/heapDumperCompression.hpp" +#include "utilities/zipLibrary.hpp" char const* FileWriter::open_writer() { @@ -62,74 +60,28 @@ char const* FileWriter::write_buf(char* buf, ssize_t size) { return nullptr; } - -typedef char const* (*GzipInitFunc)(size_t, size_t*, size_t*, int); -typedef size_t(*GzipCompressFunc)(char*, size_t, char*, size_t, char*, size_t, - int, char*, char const**); - -static GzipInitFunc gzip_init_func; -static GzipCompressFunc gzip_compress_func; - -void* GZipCompressor::load_gzip_func(char const* name) { - char path[JVM_MAXPATHLEN]; - char ebuf[1024]; - void* handle; - MutexLocker locker(Zip_lock, Monitor::_no_safepoint_check_flag); - - if (os::dll_locate_lib(path, sizeof(path), Arguments::get_dll_dir(), "zip")) { - handle = os::dll_load(path, ebuf, sizeof ebuf); - - if (handle != nullptr) { - return os::dll_lookup(handle, name); - } - } - - return nullptr; -} - char const* GZipCompressor::init(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size) { _block_size = block_size; _is_first = true; - - if (gzip_compress_func == nullptr) { - gzip_compress_func = (GzipCompressFunc) load_gzip_func("ZIP_GZip_Fully"); - - if (gzip_compress_func == nullptr) { - return "Cannot get ZIP_GZip_Fully function"; - } - } - - if (gzip_init_func == nullptr) { - gzip_init_func = (GzipInitFunc) load_gzip_func("ZIP_GZip_InitParams"); - - if (gzip_init_func == nullptr) { - return "Cannot get ZIP_GZip_InitParams function"; - } - } - - char const* result = gzip_init_func(block_size, needed_out_size, - needed_tmp_size, _level); + char const* result = ZipLibrary::init_params(block_size, needed_out_size, + needed_tmp_size, _level); *needed_out_size += 1024; // Add extra space for the comment in the first chunk. - return result; } char const* GZipCompressor::compress(char* in, size_t in_size, char* out, size_t out_size, char* tmp, size_t tmp_size, size_t* compressed_size) { char const* msg = nullptr; - if (_is_first) { char buf[128]; // Write the block size used as a comment in the first gzip chunk, so the // code used to read it later can make a good choice of the buffer sizes it uses. jio_snprintf(buf, sizeof(buf), "HPROF BLOCKSIZE=" SIZE_FORMAT, _block_size); - *compressed_size = gzip_compress_func(in, in_size, out, out_size, tmp, tmp_size, _level, - buf, &msg); + *compressed_size = ZipLibrary::compress(in, in_size, out, out_size, tmp, tmp_size, _level, buf, &msg); _is_first = false; } else { - *compressed_size = gzip_compress_func(in, in_size, out, out_size, tmp, tmp_size, _level, - nullptr, &msg); + *compressed_size = ZipLibrary::compress(in, in_size, out, out_size, tmp, tmp_size, _level, nullptr, &msg); } return msg; diff --git a/src/hotspot/share/services/heapDumperCompression.hpp b/src/hotspot/share/services/heapDumperCompression.hpp index 99482b1f7d8..a7ed3642bbe 100644 --- a/src/hotspot/share/services/heapDumperCompression.hpp +++ b/src/hotspot/share/services/heapDumperCompression.hpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 SAP SE. All rights reserved. + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,8 +91,6 @@ private: size_t _block_size; bool _is_first; - void* load_gzip_func(char const* name); - public: GZipCompressor(int level) : _level(level), _block_size(0), _is_first(false) { } diff --git a/src/hotspot/share/utilities/zipLibrary.cpp b/src/hotspot/share/utilities/zipLibrary.cpp new file mode 100644 index 00000000000..57b3e501f56 --- /dev/null +++ b/src/hotspot/share/utilities/zipLibrary.cpp @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "jvm_io.h" +#include "runtime/arguments.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/os.inline.hpp" +#include "runtime/semaphore.inline.hpp" +#include "runtime/thread.inline.hpp" +#include "utilities/zipLibrary.hpp" + + // Entry points in zip.dll for loading zip/jar file entries +typedef void**(*ZIP_Open_t)(const char* name, char** pmsg); +typedef void(*ZIP_Close_t)(jzfile* zip); +typedef jzentry* (*ZIP_FindEntry_t)(jzfile* zip, const char* name, jint* sizeP, jint* nameLen); +typedef jboolean(*ZIP_ReadEntry_t)(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf); +typedef jint(*ZIP_CRC32_t)(jint crc, const jbyte* buf, jint len); +typedef const char* (*ZIP_GZip_InitParams_t)(size_t, size_t*, size_t*, int); +typedef size_t(*ZIP_GZip_Fully_t)(char*, size_t, char*, size_t, char*, size_t, int, char*, char const**); + +static ZIP_Open_t ZIP_Open = nullptr; +static ZIP_Close_t ZIP_Close = nullptr; +static ZIP_FindEntry_t ZIP_FindEntry = nullptr; +static ZIP_ReadEntry_t ZIP_ReadEntry = nullptr; +static ZIP_CRC32_t ZIP_CRC32 = nullptr; +static ZIP_GZip_InitParams_t ZIP_GZip_InitParams = nullptr; +static ZIP_GZip_Fully_t ZIP_GZip_Fully = nullptr; + +static void* _zip_handle = nullptr; +static bool _loaded = false; + +static inline bool is_loaded() { + return Atomic::load_acquire(&_loaded); +} + +static inline bool not_loaded() { + return !is_loaded(); +} + +static void* dll_lookup(const char* name, const char* path, bool vm_exit_on_failure) { + assert(_zip_handle != nullptr, "invariant"); + void* func = os::dll_lookup(_zip_handle, name); + if (func == nullptr && vm_exit_on_failure) { + char msg[256] = ""; + jio_snprintf(&msg[0], sizeof msg, "Could not resolve \"%s\"", name); + vm_exit_during_initialization(&msg[0], path); + } + return func; +} + +static void store_function_pointers(const char* path, bool vm_exit_on_failure) { + assert(_zip_handle != nullptr, "invariant"); + ZIP_Open = CAST_TO_FN_PTR(ZIP_Open_t, dll_lookup("ZIP_Open", path, vm_exit_on_failure)); + ZIP_Close = CAST_TO_FN_PTR(ZIP_Close_t, dll_lookup("ZIP_Close", path, vm_exit_on_failure)); + ZIP_FindEntry = CAST_TO_FN_PTR(ZIP_FindEntry_t, dll_lookup("ZIP_FindEntry", path, vm_exit_on_failure)); + ZIP_ReadEntry = CAST_TO_FN_PTR(ZIP_ReadEntry_t, dll_lookup("ZIP_ReadEntry", path, vm_exit_on_failure)); + ZIP_CRC32 = CAST_TO_FN_PTR(ZIP_CRC32_t, dll_lookup("ZIP_CRC32", path, vm_exit_on_failure)); + // The following entry points are most likely optional from a zip library implementation perspective. + // Hence no vm_exit on a resolution failure. Further refactorings should investigate this, + // and if possible, streamline setting all entry points consistently. + ZIP_GZip_InitParams = CAST_TO_FN_PTR(ZIP_GZip_InitParams_t, dll_lookup("ZIP_GZip_InitParams", path, false)); + ZIP_GZip_Fully = CAST_TO_FN_PTR(ZIP_GZip_Fully_t, dll_lookup("ZIP_GZip_Fully", path, false)); +} + +static void load_zip_library(bool vm_exit_on_failure) { + assert(!is_loaded(), "should not load zip library twice"); + char path[JVM_MAXPATHLEN]; + if (os::dll_locate_lib(&path[0], sizeof path, Arguments::get_dll_dir(), "zip")) { + char ebuf[1024]; + _zip_handle = os::dll_load(&path[0], &ebuf[0], sizeof ebuf); + } + if (_zip_handle == nullptr) { + if (vm_exit_on_failure) { + vm_exit_during_initialization("Unable to load zip library", &path[0]); + } + return; + } + store_function_pointers(&path[0], vm_exit_on_failure); + Atomic::release_store(&_loaded, true); + assert(is_loaded(), "invariant"); +} + +// +// Helper mutex class that also ensures that java threads +// are in _thread_in_native when loading the zip library. +// +class ZipLibraryLoaderLock : public StackObj { + private: + static Semaphore _lock; + JavaThread* _jt; + public: + ZipLibraryLoaderLock() : _jt(nullptr) { + Thread* thread = Thread::current_or_null(); + if (thread != nullptr && thread->is_Java_thread()) { + JavaThread* const jt = JavaThread::cast(thread); + if (jt->thread_state() != _thread_in_native) { + _jt = jt; + ThreadStateTransition::transition_from_vm(jt, _thread_in_native, false); + } + } + _lock.wait(); + } + ~ZipLibraryLoaderLock() { + _lock.signal(); + if (_jt != nullptr) { + ThreadStateTransition::transition_from_native(_jt, _thread_in_vm, false); + } + } +}; + +Semaphore ZipLibraryLoaderLock::_lock(1); + +static void initialize(bool vm_exit_on_failure = true) { + if (is_loaded()) { + return; + } + ZipLibraryLoaderLock lock; + if (not_loaded()) { + load_zip_library(vm_exit_on_failure); + } +} + +void** ZipLibrary::open(const char* name, char** pmsg) { + initialize(); + assert(ZIP_Open != nullptr, "invariant"); + return ZIP_Open(name, pmsg); +} + +void ZipLibrary::close(jzfile* zip) { + assert(is_loaded(), "invariant"); + assert(ZIP_Close != nullptr, "invariant"); + ZIP_Close(zip); +} + +jzentry* ZipLibrary::find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen) { + initialize(); + assert(ZIP_FindEntry != nullptr, "invariant"); + return ZIP_FindEntry(zip, name, sizeP, nameLen); +} + +jboolean ZipLibrary::read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf) { + initialize(); + assert(ZIP_ReadEntry != nullptr, "invariant"); + return ZIP_ReadEntry(zip, entry, buf, namebuf); +} + +jint ZipLibrary::crc32(jint crc, const jbyte* buf, jint len) { + initialize(); + assert(ZIP_CRC32 != nullptr, "invariant"); + return ZIP_CRC32(crc, buf, len); +} + +const char* ZipLibrary::init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level) { + initialize(false); + if (ZIP_GZip_InitParams == nullptr) { + return "Cannot get ZIP_GZip_InitParams function"; + } + return ZIP_GZip_InitParams(block_size, needed_out_size, needed_tmp_size, level); +} + +size_t ZipLibrary::compress(char* in, size_t in_size, char* out, size_t out_size, char* tmp, size_t tmp_size, int level, char* buf, const char** pmsg) { + initialize(false); + if (ZIP_GZip_Fully == nullptr) { + *pmsg = "Cannot get ZIP_GZip_Fully function"; + return 0; + } + return ZIP_GZip_Fully(in, in_size, out, out_size, tmp, tmp_size, level, buf, pmsg); +} + +void* ZipLibrary::handle() { + initialize(); + assert(is_loaded(), "invariant"); + assert(_zip_handle != nullptr, "invariant"); + return _zip_handle; +} diff --git a/src/hotspot/share/utilities/zipLibrary.hpp b/src/hotspot/share/utilities/zipLibrary.hpp new file mode 100644 index 00000000000..73745aca2e2 --- /dev/null +++ b/src/hotspot/share/utilities/zipLibrary.hpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_UTILITIES_ZIPLIBRARY_HPP +#define SHARE_UTILITIES_ZIPLIBRARY_HPP + +#include "memory/allocation.hpp" + + // Type definitions for zip file and zip file entry +typedef void* jzfile; +typedef struct { + char* name; /* entry name */ + jlong time; /* modification time */ + jlong size; /* size of uncompressed data */ + jlong csize; /* size of compressed data (zero if uncompressed) */ + jint crc; /* crc of uncompressed data */ + char* comment; /* optional zip file comment */ + jbyte* extra; /* optional extra data */ + jlong pos; /* position of LOC header (if negative) or data */ +} jzentry; + +class ZipLibrary : AllStatic { + public: + static void** open(const char* name, char** pmsg); + static void close(jzfile* zip); + static jzentry* find_entry(jzfile* zip, const char* name, jint* sizeP, jint* nameLen); + static jboolean read_entry(jzfile* zip, jzentry* entry, unsigned char* buf, char* namebuf); + static jint crc32(jint crc, const jbyte* buf, jint len); + static const char* init_params(size_t block_size, size_t* needed_out_size, size_t* needed_tmp_size, int level); + static size_t compress(char* in, size_t in_size, char* out, size_t out_size, char* tmp, size_t tmp_size, int level, char* buf, const char** pmsg); + static void* handle(); +}; + +#endif // SHARE_UTILITIES_ZIPLIBRARY_HPP