# HG changeset patch # User jlaskey # Date 1441372328 10800 # Node ID 262b86c271b0bf05ecfba7129e3a5087bee89a7e # Parent ceb9d9044fc8c778d7095758a35148a2bb726101 8087181: Move native jimage code to its own library (maybe libjimage) Reviewed-by: alanb, lfoltan, hseigel, acorn Contributed-by: james.laskey@oracle.com, jean-francois.denise@oracle.com, roger.riggs@oracle.com diff -r ceb9d9044fc8 -r 262b86c271b0 make/aix/makefiles/mapfile-vers-debug --- a/make/aix/makefiles/mapfile-vers-debug Fri Sep 04 09:47:35 2015 +0200 +++ b/make/aix/makefiles/mapfile-vers-debug Fri Sep 04 10:12:08 2015 -0300 @@ -141,18 +141,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 make/aix/makefiles/mapfile-vers-product --- a/make/aix/makefiles/mapfile-vers-product Fri Sep 04 09:47:35 2015 +0200 +++ b/make/aix/makefiles/mapfile-vers-product Fri Sep 04 10:12:08 2015 -0300 @@ -139,18 +139,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 make/bsd/makefiles/mapfile-vers-darwin-debug --- a/make/bsd/makefiles/mapfile-vers-darwin-debug Fri Sep 04 09:47:35 2015 +0200 +++ b/make/bsd/makefiles/mapfile-vers-darwin-debug Fri Sep 04 10:12:08 2015 -0300 @@ -139,18 +139,6 @@ _JVM_Halt _JVM_HoldsLock _JVM_IHashCode - _JVM_ImageAttributeOffsets - _JVM_ImageAttributeOffsetsLength - _JVM_ImageClose - _JVM_ImageFindAttributes - _JVM_ImageGetAttributes - _JVM_ImageGetAttributesCount - _JVM_ImageGetDataAddress - _JVM_ImageGetIndexAddress - _JVM_ImageGetStringBytes - _JVM_ImageOpen - _JVM_ImageRead - _JVM_ImageReadCompressed _JVM_InitAgentProperties _JVM_InitProperties _JVM_InternString diff -r ceb9d9044fc8 -r 262b86c271b0 make/bsd/makefiles/mapfile-vers-darwin-product --- a/make/bsd/makefiles/mapfile-vers-darwin-product Fri Sep 04 09:47:35 2015 +0200 +++ b/make/bsd/makefiles/mapfile-vers-darwin-product Fri Sep 04 10:12:08 2015 -0300 @@ -139,18 +139,6 @@ _JVM_Halt _JVM_HoldsLock _JVM_IHashCode - _JVM_ImageAttributeOffsets - _JVM_ImageAttributeOffsetsLength - _JVM_ImageClose - _JVM_ImageFindAttributes - _JVM_ImageGetAttributes - _JVM_ImageGetAttributesCount - _JVM_ImageGetDataAddress - _JVM_ImageGetIndexAddress - _JVM_ImageGetStringBytes - _JVM_ImageOpen - _JVM_ImageRead - _JVM_ImageReadCompressed _JVM_InitAgentProperties _JVM_InitProperties _JVM_InternString diff -r ceb9d9044fc8 -r 262b86c271b0 make/bsd/makefiles/mapfile-vers-debug --- a/make/bsd/makefiles/mapfile-vers-debug Fri Sep 04 09:47:35 2015 +0200 +++ b/make/bsd/makefiles/mapfile-vers-debug Fri Sep 04 10:12:08 2015 -0300 @@ -141,18 +141,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 make/bsd/makefiles/mapfile-vers-product --- a/make/bsd/makefiles/mapfile-vers-product Fri Sep 04 09:47:35 2015 +0200 +++ b/make/bsd/makefiles/mapfile-vers-product Fri Sep 04 10:12:08 2015 -0300 @@ -141,18 +141,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 make/linux/makefiles/mapfile-vers-debug --- a/make/linux/makefiles/mapfile-vers-debug Fri Sep 04 09:47:35 2015 +0200 +++ b/make/linux/makefiles/mapfile-vers-debug Fri Sep 04 10:12:08 2015 -0300 @@ -141,18 +141,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 make/linux/makefiles/mapfile-vers-product --- a/make/linux/makefiles/mapfile-vers-product Fri Sep 04 09:47:35 2015 +0200 +++ b/make/linux/makefiles/mapfile-vers-product Fri Sep 04 10:12:08 2015 -0300 @@ -141,18 +141,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 make/solaris/makefiles/mapfile-vers --- a/make/solaris/makefiles/mapfile-vers Fri Sep 04 09:47:35 2015 +0200 +++ b/make/solaris/makefiles/mapfile-vers Fri Sep 04 10:12:08 2015 -0300 @@ -141,18 +141,6 @@ JVM_Halt; JVM_HoldsLock; JVM_IHashCode; - JVM_ImageAttributeOffsets; - JVM_ImageAttributeOffsetsLength; - JVM_ImageClose; - JVM_ImageFindAttributes; - JVM_ImageGetAttributes; - JVM_ImageGetAttributesCount; - JVM_ImageGetDataAddress; - JVM_ImageGetIndexAddress; - JVM_ImageGetStringBytes; - JVM_ImageOpen; - JVM_ImageRead; - JVM_ImageReadCompressed; JVM_InitAgentProperties; JVM_InitProperties; JVM_InternString; diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/classLoader.cpp --- a/src/share/vm/classfile/classLoader.cpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/classfile/classLoader.cpp Fri Sep 04 10:12:08 2015 -0300 @@ -28,8 +28,8 @@ #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderExt.hpp" -#include "classfile/imageFile.hpp" #include "classfile/javaClasses.hpp" +#include "classfile/jimage.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "compiler/compileBroker.hpp" @@ -58,6 +58,7 @@ #include "runtime/os.hpp" #include "runtime/threadCritical.hpp" #include "runtime/timer.hpp" +#include "runtime/vm_version.hpp" #include "services/management.hpp" #include "services/threadService.hpp" #include "utilities/events.hpp" @@ -68,7 +69,7 @@ #include "classfile/sharedPathsMiscInfo.hpp" #endif -// Entry points in zip.dll for loading zip/jar file entries and image file entries +// Entry points in zip.dll for loading zip/jar file entries typedef void * * (JNICALL *ZipOpen_t)(const char *name, char **pmsg); typedef void (JNICALL *ZipClose_t)(jzfile *zip); @@ -89,6 +90,15 @@ static ZipInflateFully_t ZipInflateFully = NULL; static Crc32_t Crc32 = NULL; +// Entry points for jimage.dll for loading jimage file entries + +static JImageOpen_t JImageOpen = NULL; +static JImageClose_t JImageClose = NULL; +static JImagePackageToModule_t JImagePackageToModule = NULL; +static JImageFindResource_t JImageFindResource = NULL; +static JImageGetResource_t JImageGetResource = NULL; +static JImageResourceIterator_t JImageResourceIterator = NULL; + // Globals PerfCounter* ClassLoader::_perf_accumulated_time = NULL; @@ -141,6 +151,15 @@ return (strncmp(str, str_to_find, str_to_find_len) == 0); } +static const char* get_jimage_version_string() { + static char version_string[10] = ""; + if (version_string[0] == '\0') { + jio_snprintf(version_string, sizeof(version_string), "%d.%d", + Abstract_VM_Version::vm_minor_version(), Abstract_VM_Version::vm_micro_version()); + } + return (const char*)version_string; +} + bool string_ends_with(const char* str, const char* str_to_find) { size_t str_len = strlen(str); size_t str_to_find_len = strlen(str_to_find); @@ -272,98 +291,114 @@ } } -ClassPathImageEntry::ClassPathImageEntry(ImageFileReader* image) : +ClassPathImageEntry::ClassPathImageEntry(JImageFile* jimage, const char* name) : ClassPathEntry(), - _image(image), - _module_data(NULL) { - guarantee(image != NULL, "image file is null"); - - char module_data_name[JVM_MAXPATHLEN]; - ImageModuleData::module_data_name(module_data_name, _image->name()); - _module_data = new ImageModuleData(_image, module_data_name); + _jimage(jimage) { + guarantee(jimage != NULL, "jimage file is null"); + guarantee(name != NULL, "jimage file name is null"); + size_t len = strlen(name) + 1; + _name = NEW_C_HEAP_ARRAY(const char, len, mtClass); + strncpy((char *)_name, name, len); } ClassPathImageEntry::~ClassPathImageEntry() { - if (_module_data != NULL) { - delete _module_data; - _module_data = NULL; + if (_name != NULL) { + FREE_C_HEAP_ARRAY(const char, _name); + _name = NULL; } - - if (_image != NULL) { - ImageFileReader::close(_image); - _image = NULL; + if (_jimage != NULL) { + (*JImageClose)(_jimage); + _jimage = NULL; } } -const char* ClassPathImageEntry::name() { - return _image ? _image->name() : ""; +void ClassPathImageEntry::name_to_package(const char* name, char* buffer, int length) { + const char *pslash = strrchr(name, '/'); + if (pslash == NULL) { + buffer[0] = '\0'; + return; + } + int len = pslash - name; +#if INCLUDE_CDS + if (len <= 0 && DumpSharedSpaces) { + buffer[0] = '\0'; + return; + } +#endif + assert(len > 0, "Bad length for package name"); + if (len >= length) { + buffer[0] = '\0'; + return; + } + // drop name after last slash (including slash) + // Ex., "java/lang/String.class" => "java/lang" + strncpy(buffer, name, len); + // ensure string termination (strncpy does not guarantee) + buffer[len] = '\0'; } +// For a class in a named module, look it up in the jimage file using this syntax: +// /// +// +// Assumptions: +// 1. There are no unnamed modules in the jimage file. +// 2. A package is in at most one module in the jimage file. +// ClassFileStream* ClassPathImageEntry::open_stream(const char* name, TRAPS) { - ImageLocation location; - bool found = _image->find_location(name, location); - - if (!found) { - const char *pslash = strrchr(name, '/'); - int len = pslash - name; + jlong size; + JImageLocationRef location = (*JImageFindResource)(_jimage, "", get_jimage_version_string(), name, &size); - // NOTE: IMAGE_MAX_PATH is used here since this path is internal to the jimage - // (effectively unlimited.) There are several JCK tests that use paths over - // 1024 characters long, the limit on Windows systems. - if (pslash && 0 < len && len < IMAGE_MAX_PATH) { - - char path[IMAGE_MAX_PATH]; - strncpy(path, name, len); - path[len] = '\0'; - const char* moduleName = _module_data->package_to_module(path); - - if (moduleName != NULL && (len + strlen(moduleName) + 2) < IMAGE_MAX_PATH) { - jio_snprintf(path, IMAGE_MAX_PATH - 1, "/%s/%s", moduleName, name); - location.clear_data(); - found = _image->find_location(path, location); - } + if (location == 0) { + char package[JIMAGE_MAX_PATH]; + name_to_package(name, package, JIMAGE_MAX_PATH); + if (package[0] != '\0') { + const char* module = (*JImagePackageToModule)(_jimage, package); + if (module == NULL) { + module = "java.base"; + } + location = (*JImageFindResource)(_jimage, module, get_jimage_version_string(), name, &size); } } - if (found) { - u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED); + if (location != 0) { if (UsePerfData) { ClassLoader::perf_sys_classfile_bytes_read()->inc(size); } - u1* data = NEW_RESOURCE_ARRAY(u1, size); - _image->get_resource(location, data); - return new ClassFileStream(data, (int)size, _image->name()); // Resource allocated + char* data = NEW_RESOURCE_ARRAY(char, size); + (*JImageGetResource)(_jimage, location, data, size); + return new ClassFileStream((u1*)data, (int)size, _name); // Resource allocated } return NULL; } #ifndef PRODUCT +bool ctw_visitor(JImageFile* jimage, + const char* module_name, const char* version, const char* package, + const char* name, const char* extension, void* arg) { + if (strcmp(extension, "class") == 0) { + Thread* THREAD = Thread::current(); + char path[JIMAGE_MAX_PATH]; + jio_snprintf(path, JIMAGE_MAX_PATH - 1, "%s/%s.class", package, name); + ClassLoader::compile_the_world_in(path, *(Handle*)arg, THREAD); + return !HAS_PENDING_EXCEPTION; + } + return true; +} + 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 length = _image->table_length(); - for (u4 i = 0; i < length; i++) { - u1* location_data = _image->get_location_data(i); - - if (location_data != NULL) { - ImageLocation location(location_data); - char path[IMAGE_MAX_PATH]; - _image->location_path(location, path, IMAGE_MAX_PATH); - ClassLoader::compile_the_world_in(path, loader, CHECK); + (*JImageResourceIterator)(_jimage, (JImageResourceVisitor_t)ctw_visitor, (void *)&loader); + 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"); } } - 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() { @@ -490,7 +525,7 @@ JavaThread* thread = JavaThread::current(); ClassPathEntry* new_entry = NULL; if ((st->st_mode & S_IFREG) == S_IFREG) { - // Regular file, should be a zip or image file + // Regular file, should be a zip or jimage file // Canonicalized filename char canonical_path[JVM_MAXPATHLEN]; if (!get_canonical_path(path, canonical_path, JVM_MAXPATHLEN)) { @@ -501,9 +536,10 @@ return NULL; } } - ImageFileReader* image = ImageFileReader::open(canonical_path); - if (image != NULL) { - new_entry = new ClassPathImageEntry(image); + jint error; + JImageFile* jimage =(*JImageOpen)(canonical_path, &error); + if (jimage != NULL) { + new_entry = new ClassPathImageEntry(jimage, canonical_path); } else { char* error_msg = NULL; jzfile* zip; @@ -682,6 +718,35 @@ // This lookup only works on 1.3. Do not check for non-null here } +void ClassLoader::load_jimage_library() { + // First make sure native library is loaded + os::native_java_library(); + // Load jimage library + char path[JVM_MAXPATHLEN]; + char ebuf[1024]; + void* handle = NULL; + if (os::dll_build_name(path, sizeof(path), Arguments::get_dll_dir(), "jimage")) { + handle = os::dll_load(path, ebuf, sizeof ebuf); + } + if (handle == NULL) { + vm_exit_during_initialization("Unable to load jimage library", path); + } + + // Lookup jimage entry points + JImageOpen = CAST_TO_FN_PTR(JImageOpen_t, os::dll_lookup(handle, "JIMAGE_Open")); + guarantee(JImageOpen != NULL, "function JIMAGE_Open not found"); + JImageClose = CAST_TO_FN_PTR(JImageClose_t, os::dll_lookup(handle, "JIMAGE_Close")); + guarantee(JImageClose != NULL, "function JIMAGE_Close not found"); + JImagePackageToModule = CAST_TO_FN_PTR(JImagePackageToModule_t, os::dll_lookup(handle, "JIMAGE_PackageToModule")); + guarantee(JImagePackageToModule != NULL, "function JIMAGE_PackageToModule not found"); + JImageFindResource = CAST_TO_FN_PTR(JImageFindResource_t, os::dll_lookup(handle, "JIMAGE_FindResource")); + guarantee(JImageFindResource != NULL, "function JIMAGE_FindResource not found"); + JImageGetResource = CAST_TO_FN_PTR(JImageGetResource_t, os::dll_lookup(handle, "JIMAGE_GetResource")); + guarantee(JImageGetResource != NULL, "function JIMAGE_GetResource not found"); + JImageResourceIterator = CAST_TO_FN_PTR(JImageResourceIterator_t, os::dll_lookup(handle, "JIMAGE_ResourceIterator")); + guarantee(JImageResourceIterator != NULL, "function JIMAGE_ResourceIterator not found"); +} + jboolean ClassLoader::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) { return (*ZipInflateFully)(in, inSize, out, outSize, pmsg); } @@ -1086,6 +1151,8 @@ // lookup zip library entry points load_zip_library(); + // lookup jimage library entry points + load_jimage_library(); #if INCLUDE_CDS // initialize search path if (DumpSharedSpaces) { diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/classLoader.hpp --- a/src/share/vm/classfile/classLoader.hpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/classfile/classLoader.hpp Fri Sep 04 10:12:08 2015 -0300 @@ -37,8 +37,7 @@ // Class path entry (directory or zip file) -class ImageFileReader; -class ImageModuleData; +class JImageFile; class ClassPathEntry: public CHeapObj { private: @@ -52,7 +51,7 @@ } virtual bool is_jar_file() = 0; virtual const char* name() = 0; - virtual ImageFileReader* image() = 0; + virtual JImageFile* jimage() = 0; // Constructor ClassPathEntry(); // Attempt to locate file_name through this class path entry. @@ -70,7 +69,7 @@ public: bool is_jar_file() { return false; } const char* name() { return _dir; } - ImageFileReader* image() { return NULL; } + JImageFile* jimage() { return NULL; } ClassPathDirEntry(const char* dir); ClassFileStream* open_stream(const char* name, TRAPS); // Debugging @@ -100,7 +99,7 @@ public: bool is_jar_file() { return true; } const char* name() { return _zip_name; } - ImageFileReader* image() { return NULL; } + JImageFile* jimage() { return NULL; } ClassPathZipEntry(jzfile* zip, const char* zip_name); ~ClassPathZipEntry(); u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS); @@ -115,16 +114,16 @@ // For java image files class ClassPathImageEntry: public ClassPathEntry { private: - ImageFileReader* _image; - ImageModuleData* _module_data; + JImageFile* _jimage; + const char* _name; public: bool is_jar_file() { return false; } - bool is_open() { return _image != NULL; } - const char* name(); - ImageFileReader* image() { return _image; } - ImageModuleData* module_data() { return _module_data; } - ClassPathImageEntry(ImageFileReader* image); + bool is_open() { return _jimage != NULL; } + const char* name() { return _name == NULL ? "" : _name; } + JImageFile* jimage() { return _jimage; } + ClassPathImageEntry(JImageFile* jimage, const char* name); ~ClassPathImageEntry(); + static void name_to_package(const char* name, char* buffer, int length); ClassFileStream* open_stream(const char* name, TRAPS); // Debugging @@ -206,6 +205,7 @@ static void setup_search_path(const char *class_path); static void load_zip_library(); + static void load_jimage_library(); static ClassPathEntry* create_class_path_entry(const char *path, const struct stat* st, bool throw_exception, TRAPS); diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/imageDecompressor.cpp --- a/src/share/vm/classfile/imageDecompressor.cpp Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2015, 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 "runtime/thread.inline.hpp" -#include "classfile/imageDecompressor.hpp" -#include "runtime/thread.hpp" -#include "utilities/bytes.hpp" - -/* - * Allocate in C Heap not in resource area, otherwise JVM crashes. - * This array life time is the VM life time. Array is never freed and - * is not expected to contain more than few references. - */ -GrowableArray* ImageDecompressor::_decompressors = - new(ResourceObj::C_HEAP, mtInternal) GrowableArray(2, true); - -static Symbol* createSymbol(const char* str) { - Thread* THREAD = Thread::current(); - Symbol* sym = SymbolTable::lookup(str, (int) strlen(str), THREAD); - if (HAS_PENDING_EXCEPTION) { - warning("can't create symbol\n"); - CLEAR_PENDING_EXCEPTION; - return NULL; - } - return sym; -} - -/* - * Initialize the array of decompressors. - */ -bool image_decompressor_init() { - Symbol* zipSymbol = createSymbol("zip"); - if (zipSymbol == NULL) { - return false; - } - ImageDecompressor::add_decompressor(new ZipDecompressor(zipSymbol)); - - return true; -} - -/* - * Decompression entry point. Called from ImageFileReader::get_resource. - */ -void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed, - u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap) { - bool has_header = false; - u1* decompressed_resource = compressed; - u1* compressed_resource = compressed; - - // Resource could have been transformed by a stack of decompressors. - // Iterate and decompress resources until there is no more header. - do { - ResourceHeader _header; - memcpy(&_header, compressed_resource, sizeof (ResourceHeader)); - has_header = _header._magic == ResourceHeader::resource_header_magic; - if (has_header) { - // decompressed_resource array contains the result of decompression - // when a resource content is terminal, it means that it is an actual resource, - // not an intermediate not fully uncompressed content. In this case - // the resource is allocated as an mtClass, otherwise as an mtOther - decompressed_resource = is_C_heap && _header._is_terminal ? - NEW_C_HEAP_ARRAY(u1, _header._uncompressed_size, mtClass) : - NEW_C_HEAP_ARRAY(u1, _header._uncompressed_size, mtOther); - // Retrieve the decompressor name - const char* decompressor_name = strings->get(_header._decompressor_name_offset); - if (decompressor_name == NULL) warning("image decompressor not found\n"); - guarantee(decompressor_name, "image decompressor not found"); - // Retrieve the decompressor instance - ImageDecompressor* decompressor = get_decompressor(decompressor_name); - if (decompressor == NULL) { - warning("image decompressor %s not found\n", decompressor_name); - } - guarantee(decompressor, "image decompressor not found"); - u1* compressed_resource_base = compressed_resource; - compressed_resource += ResourceHeader::resource_header_length; - // Ask the decompressor to decompress the compressed content - decompressor->decompress_resource(compressed_resource, decompressed_resource, - &_header, strings); - if (compressed_resource_base != compressed) { - FREE_C_HEAP_ARRAY(char, compressed_resource_base); - } - compressed_resource = decompressed_resource; - } - } while (has_header); - memcpy(uncompressed, decompressed_resource, uncompressed_size); -} - -// Zip decompressor - -void ZipDecompressor::decompress_resource(u1* data, u1* uncompressed, - ResourceHeader* header, const ImageStrings* strings) { - char* msg = NULL; - jboolean res = ClassLoader::decompress(data, header->_size, uncompressed, - header->_uncompressed_size, &msg); - if (!res) warning("decompression failed due to %s\n", msg); - guarantee(res, "decompression failed"); -} - -// END Zip Decompressor diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/imageDecompressor.hpp --- a/src/share/vm/classfile/imageDecompressor.hpp Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2015, 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_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP -#define SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP - -#include "runtime/thread.inline.hpp" -#include "classfile/classLoader.hpp" -#include "classfile/imageFile.hpp" -#include "classfile/symbolTable.hpp" -#include "oops/symbol.hpp" -#include "utilities/growableArray.hpp" - -/* - * Compressed resources located in image have an header. - * This header contains: - * - _magic: A magic u4, required to retrieved the header in the compressed content - * - _size: The size of the compressed resource. - * - _uncompressed_size: The uncompressed size of the compressed resource. - * - _decompressor_name_offset: The ImageDecompressor instance name StringsTable offset. - * - _decompressor_config_offset: StringsTable offset of configuration that could be needed by - * the decompressor in order to decompress. - * - _is_terminal: 1: the compressed content is terminal. Uncompressing it would - * create the actual resource. 0: the compressed content is not terminal. Uncompressing it - * will result in a compressed content to be decompressed (This occurs when a stack of compressors - * have been used to compress the resource. - */ -struct ResourceHeader { - /* Length of header, needed to retrieve content offset */ - static const u1 resource_header_length = 21; - /* magic bytes that identifies a compressed resource header*/ - static const u4 resource_header_magic = 0xCAFEFAFA; - u4 _magic; // Resource header - u4 _size; // Resource size - u4 _uncompressed_size; // Expected uncompressed size - u4 _decompressor_name_offset; // Strings table decompressor offset - u4 _decompressor_config_offset; // Strings table config offset - u1 _is_terminal; // Last decompressor 1, otherwise 0. -}; - -/* - * Resources located in jimage file can be compressed. Compression occurs at - * jimage file creation time. When compressed a resource is added an header that - * contains the name of the compressor that compressed it. - * Various compression strategies can be applied to compress a resource. - * The same resource can even be compressed multiple time by a stack of compressors. - * At runtime, a resource is decompressed in a loop until there is no more header - * meaning that the resource is equivalent to the not compressed resource. - * In each iteration, the name of the compressor located in the current header - * is used to retrieve the associated instance of ImageDecompressor. - * For example “zip” is the name of the compressor that compresses resources - * using the zip algorithm. The ZipDecompressor class name is also “zip”. - * ImageDecompressor instances are retrieved from a static array in which - * they are registered. - */ -class ImageDecompressor: public CHeapObj { - -private: - const Symbol* _name; - - /* - * Array of concrete decompressors. This array is used to retrieve the decompressor - * that can handle resource decompression. - */ - static GrowableArray* _decompressors; - - /* - * Identifier of a decompressor. This name is the identification key to retrieve - * decompressor from a resource header. - */ - inline const Symbol* get_name() const { return _name; } - -protected: - ImageDecompressor(const Symbol* name) : _name(name) { - } - virtual void decompress_resource(u1* data, u1* uncompressed, - ResourceHeader* header, const ImageStrings* strings) = 0; - -public: - inline static void add_decompressor(ImageDecompressor* decompressor) { - _decompressors->append(decompressor); - } - inline static ImageDecompressor* get_decompressor(const char * decompressor_name) { - Thread* THREAD = Thread::current(); - TempNewSymbol sym = SymbolTable::new_symbol(decompressor_name, - (int) strlen(decompressor_name), CHECK_NULL); - if (HAS_PENDING_EXCEPTION) { - warning("can't create symbol\n"); - CLEAR_PENDING_EXCEPTION; - return NULL; - } - for (int i = 0; i < _decompressors->length(); i++) { - ImageDecompressor* decompressor = _decompressors->at(i); - if (decompressor->get_name()->fast_compare(sym) == 0) { - return decompressor; - } - } - guarantee(false, "No decompressor found."); - return NULL; - } - static void decompress_resource(u1* compressed, u1* uncompressed, - u4 uncompressed_size, const ImageStrings* strings, bool is_C_heap); -}; - -/** - * Zip decompressor. - */ -class ZipDecompressor : public ImageDecompressor { -public: - ZipDecompressor(const Symbol* sym) : ImageDecompressor(sym) { } - void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header, - const ImageStrings* strings); -}; - -#endif // SHARE_VM_CLASSFILE_IMAGEDECOMPRESSOR_HPP diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/imageFile.cpp --- a/src/share/vm/classfile/imageFile.cpp Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,546 +0,0 @@ -/* - * Copyright (c) 2015, 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 "classfile/imageDecompressor.hpp" -#include "classfile/imageFile.hpp" -#include "memory/resourceArea.hpp" -#include "runtime/mutex.hpp" -#include "runtime/mutexLocker.hpp" -#include "runtime/os.inline.hpp" -#include "utilities/endian.hpp" -#include "utilities/growableArray.hpp" - -// Image files are an alternate file format for storing classes and resources. The -// goal is to supply file access which is faster and smaller than the jar format. -// -// (More detailed nodes in the header.) -// - -// Compute the Perfect Hashing hash code for the supplied UTF-8 string. -s4 ImageStrings::hash_code(const char* string, s4 seed) { - // Access bytes as unsigned. - u1* bytes = (u1*)string; - // Compute hash code. - for (u1 byte = *bytes++; byte; byte = *bytes++) { - seed = (seed * HASH_MULTIPLIER) ^ byte; - } - // Ensure the result is not signed. - return seed & 0x7FFFFFFF; -} - -// Match up a string in a perfect hash table. Result still needs validation -// for precise match (false positive.) -s4 ImageStrings::find(Endian* endian, const char* name, s4* redirect, u4 length) { - // If the table is empty, then short cut. - if (redirect == NULL || length == 0) { - return NOT_FOUND; - } - // Compute the basic perfect hash for name. - s4 hash_code = ImageStrings::hash_code(name); - // Modulo table size. - s4 index = hash_code % length; - // Get redirect entry. - // value == 0 then not found - // value < 0 then -1 - value is true index - // value > 0 then value is seed for recomputing hash. - s4 value = endian->get(redirect[index]); - // if recompute is required. - if (value > 0) { - // Entry collision value, need to recompute hash. - hash_code = ImageStrings::hash_code(name, value); - // Modulo table size. - return hash_code % length; - } else if (value < 0) { - // Compute direct index. - return -1 - value; - } - // No entry found. - return NOT_FOUND; -} - -// Test to see if UTF-8 string begins with the start UTF-8 string. If so, -// return non-NULL address of remaining portion of string. Otherwise, return -// NULL. Used to test sections of a path without copying from image string -// table. -const char* ImageStrings::starts_with(const char* string, const char* start) { - char ch1, ch2; - // Match up the strings the best we can. - while ((ch1 = *string) && (ch2 = *start)) { - if (ch1 != ch2) { - // Mismatch, return NULL. - return NULL; - } - // Next characters. - string++, start++; - } - // Return remainder of string. - return string; -} - -// Inflates the attribute stream into individual values stored in the long -// array _attributes. This allows an attribute value to be quickly accessed by -// direct indexing. Unspecified values default to zero (from constructor.) -void ImageLocation::set_data(u1* data) { - // Deflate the attribute stream into an array of attributes. - u1 byte; - // Repeat until end header is found. - while ((byte = *data)) { - // Extract kind from header byte. - u1 kind = attribute_kind(byte); - guarantee(kind < ATTRIBUTE_COUNT, "invalid image location attribute"); - // Extract length of data (in bytes). - u1 n = attribute_length(byte); - // Read value (most significant first.) - _attributes[kind] = attribute_value(data + 1, n); - // Position to next attribute by skipping attribute header and data bytes. - data += n + 1; - } -} - -// Zero all attribute values. -void ImageLocation::clear_data() { - // Set defaults to zero. - memset(_attributes, 0, sizeof(_attributes)); -} - -// ImageModuleData constructor maps out sub-tables for faster access. -ImageModuleData::ImageModuleData(const ImageFileReader* image_file, - const char* module_data_name) : - _image_file(image_file), - _endian(image_file->endian()), - _strings(image_file->get_strings()) { - // Retrieve the resource containing the module data for the image file. - ImageLocation location; - bool found = image_file->find_location(module_data_name, location); - guarantee(found, "missing module data"); - u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED); - _data = (u1*)NEW_C_HEAP_ARRAY(char, data_size, mtClass); - _image_file->get_resource(location, _data); - // Map out the header. - _header = (Header*)_data; - // Get the package to module entry count. - u4 ptm_count = _header->ptm_count(_endian); - // Get the module to package entry count. - u4 mtp_count = _header->mtp_count(_endian); - // Compute the offset of the package to module perfect hash redirect. - u4 ptm_redirect_offset = sizeof(Header); - // Compute the offset of the package to module data. - u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4); - // Compute the offset of the module to package perfect hash redirect. - u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData); - // Compute the offset of the module to package data. - u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4); - // Compute the offset of the module to package tables. - u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData); - // Compute the address of the package to module perfect hash redirect. - _ptm_redirect = (s4*)(_data + ptm_redirect_offset); - // Compute the address of the package to module data. - _ptm_data = (PTMData*)(_data + ptm_data_offset); - // Compute the address of the module to package perfect hash redirect. - _mtp_redirect = (s4*)(_data + mtp_redirect_offset); - // Compute the address of the module to package data. - _mtp_data = (MTPData*)(_data + mtp_data_offset); - // Compute the address of the module to package tables. - _mtp_packages = (s4*)(_data + mtp_packages_offset); -} - -// Release module data resource. -ImageModuleData::~ImageModuleData() { - if (_data != NULL) { - FREE_C_HEAP_ARRAY(u1, _data); - } -} - -// Return the name of the module data resource. Ex. "./lib/modules/file.jimage" -// yields "file.jdata" -void ImageModuleData::module_data_name(char* buffer, const char* image_file_name) { - // Locate the last slash in the file name path. - const char* slash = strrchr(image_file_name, os::file_separator()[0]); - // Trim the path to name and extension. - const char* name = slash != NULL ? slash + 1 : (char *)image_file_name; - // Locate the extension period. - const char* dot = strrchr(name, '.'); - guarantee(dot, "missing extension on jimage name"); - // Trim to only base name. - int length = dot - name; - strncpy(buffer, name, length); - buffer[length] = '\0'; - // Append extension. - strcat(buffer, ".jdata"); -} - -// Return the module in which a package resides. Returns NULL if not found. -const char* ImageModuleData::package_to_module(const char* package_name) { - // Search the package to module table. - s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect, - _header->ptm_count(_endian)); - // If entry is found. - if (index != ImageStrings::NOT_FOUND) { - // Retrieve the package to module entry. - PTMData* data = _ptm_data + index; - // Verify that it is the correct data. - if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) { - return NULL; - } - // Return the module name. - return get_string(data->module_name_offset(_endian)); - } - return NULL; -} - -// Returns all the package names in a module. Returns NULL if module not found. -GrowableArray* ImageModuleData::module_to_packages(const char* module_name) { - // Search the module to package table. - s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect, - _header->mtp_count(_endian)); - // If entry is found. - if (index != ImageStrings::NOT_FOUND) { - // Retrieve the module to package entry. - MTPData* data = _mtp_data + index; - // Verify that it is the correct data. - if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) { - return NULL; - } - // Construct an array of all the package entries. - GrowableArray* packages = new GrowableArray(); - s4 package_offset = data->package_offset(_endian); - for (u4 i = 0; i < data->package_count(_endian); i++) { - u4 package_name_offset = mtp_package(package_offset + i); - const char* package_name = get_string(package_name_offset); - packages->append(package_name); - } - return packages; - } - return NULL; -} - -// Table to manage multiple opens of an image file. -GrowableArray* ImageFileReader::_reader_table = - new(ResourceObj::C_HEAP, mtInternal) GrowableArray(2, true); - -// Open an image file, reuse structure if file already open. -ImageFileReader* ImageFileReader::open(const char* name, bool big_endian) { - // Lock out _reader_table. - MutexLocker ml(ImageFileReaderTable_lock); - ImageFileReader* reader; - // Search for an exist image file. - for (int i = 0; i < _reader_table->length(); i++) { - // Retrieve table entry. - reader = _reader_table->at(i); - // If name matches, then reuse (bump up use count.) - if (strcmp(reader->name(), name) == 0) { - reader->inc_use(); - return reader; - } - } - // Need a new image reader. - reader = new ImageFileReader(name, big_endian); - bool opened = reader->open(); - // If failed to open. - if (!opened) { - delete reader; - return NULL; - } - // Bump use count and add to table. - reader->inc_use(); - _reader_table->append(reader); - return reader; -} - -// Close an image file if the file is not in use elsewhere. -void ImageFileReader::close(ImageFileReader *reader) { - // Lock out _reader_table. - MutexLocker ml(ImageFileReaderTable_lock); - // If last use then remove from table and then close. - if (reader->dec_use()) { - _reader_table->remove(reader); - delete reader; - } -} - -// Return an id for the specifed ImageFileReader. -u8 ImageFileReader::readerToID(ImageFileReader *reader) { - // ID is just the cloaked reader address. - return (u8)reader; -} - -// Validate the image id. -bool ImageFileReader::idCheck(u8 id) { - // Make sure the ID is a managed (_reader_table) reader. - MutexLocker ml(ImageFileReaderTable_lock); - return _reader_table->contains((ImageFileReader*)id); -} - -// Return an id for the specifed ImageFileReader. -ImageFileReader* ImageFileReader::idToReader(u8 id) { -#ifdef PRODUCT - // Fast convert. - return (ImageFileReader*)id; -#else - // Do a slow check before fast convert. - return idCheck(id) ? (ImageFileReader*)id : NULL; -#endif -} - -// Constructor intializes to a closed state. -ImageFileReader::ImageFileReader(const char* name, bool big_endian) { - // Copy the image file name. - _name = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtClass); - strcpy(_name, name); - // Initialize for a closed file. - _fd = -1; - _endian = Endian::get_handler(big_endian); - _index_data = NULL; -} - -// Close image and free up data structures. -ImageFileReader::~ImageFileReader() { - // Ensure file is closed. - close(); - // Free up name. - if (_name != NULL) { - FREE_C_HEAP_ARRAY(char, _name); - _name = NULL; - } -} - -// Open image file for read access. -bool ImageFileReader::open() { - // If file exists open for reading. - struct stat st; - if (os::stat(_name, &st) != 0 || - (st.st_mode & S_IFREG) != S_IFREG || - (_fd = os::open(_name, 0, O_RDONLY)) == -1) { - return false; - } - // Retrieve the file size. - _file_size = (u8)st.st_size; - // Read image file header and verify it has a valid header. - size_t header_size = sizeof(ImageHeader); - if (_file_size < header_size || - !read_at((u1*)&_header, header_size, 0) || - _header.magic(_endian) != IMAGE_MAGIC || - _header.major_version(_endian) != MAJOR_VERSION || - _header.minor_version(_endian) != MINOR_VERSION) { - close(); - return false; - } - // Size of image index. - _index_size = index_size(); - // Make sure file is large enough to contain the index. - if (_file_size < _index_size) { - return false; - } - // Determine how much of the image is memory mapped. - off_t map_size = (off_t)(MemoryMapImage ? _file_size : _index_size); - // Memory map image (minimally the index.) - _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, map_size, true, false); - guarantee(_index_data, "image file not memory mapped"); - // Retrieve length of index perfect hash table. - u4 length = table_length(); - // Compute offset of the perfect hash table redirect table. - u4 redirect_table_offset = (u4)header_size; - // Compute offset of index attribute offsets. - u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4); - // Compute offset of index location attribute data. - u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4); - // Compute offset of index string table. - u4 string_bytes_offset = location_bytes_offset + locations_size(); - // Compute address of the perfect hash table redirect table. - _redirect_table = (s4*)(_index_data + redirect_table_offset); - // Compute address of index attribute offsets. - _offsets_table = (u4*)(_index_data + offsets_table_offset); - // Compute address of index location attribute data. - _location_bytes = _index_data + location_bytes_offset; - // Compute address of index string table. - _string_bytes = _index_data + string_bytes_offset; - // Successful open. - return true; -} - -// Close image file. -void ImageFileReader::close() { - // Dealllocate the index. - if (_index_data != NULL) { - os::unmap_memory((char*)_index_data, _index_size); - _index_data = NULL; - } - // Close file. - if (_fd != -1) { - os::close(_fd); - _fd = -1; - } -} - -// Read directly from the file. -bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const { - return os::read_at(_fd, data, size, offset) == size; -} - -// Find the location attributes associated with the path. Returns true if -// the location is found, false otherwise. -bool ImageFileReader::find_location(const char* path, ImageLocation& location) const { - // Locate the entry in the index perfect hash table. - s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length()); - // If is found. - if (index != ImageStrings::NOT_FOUND) { - // Get address of first byte of location attribute stream. - u1* data = get_location_data(index); - // Expand location attributes. - location.set_data(data); - // Make sure result is not a false positive. - return verify_location(location, path); - } - return false; -} - -// Assemble the location path from the string fragments indicated in the location attributes. -void ImageFileReader::location_path(ImageLocation& location, char* path, size_t max) const { - // Manage the image string table. - ImageStrings strings(_string_bytes, _header.strings_size(_endian)); - // Position to first character of the path buffer. - char* next = path; - // Temp for string length. - size_t length; - // Get module string. - const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings); - // If module string is not empty string. - if (*module != '\0') { - // Get length of module name. - length = strlen(module); - // Make sure there is no buffer overflow. - guarantee(next - path + length + 2 < max, "buffer overflow"); - // Append '/module/'. - *next++ = '/'; - strcpy(next, module); next += length; - *next++ = '/'; - } - // Get parent (package) string. - const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings); - // If parent string is not empty string. - if (*parent != '\0') { - // Get length of module string. - length = strlen(parent); - // Make sure there is no buffer overflow. - guarantee(next - path + length + 1 < max, "buffer overflow"); - // Append 'patent/' . - strcpy(next, parent); next += length; - *next++ = '/'; - } - // Get base name string. - const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings); - // Get length of base name. - length = strlen(base); - // Make sure there is no buffer overflow. - guarantee(next - path + length < max, "buffer overflow"); - // Append base name. - strcpy(next, base); next += length; - // Get extension string. - const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings); - // If extension string is not empty string. - if (*extension != '\0') { - // Get length of extension string. - length = strlen(extension); - // Make sure there is no buffer overflow. - guarantee(next - path + length + 1 < max, "buffer overflow"); - // Append '.extension' . - *next++ = '.'; - strcpy(next, extension); next += length; - } - // Make sure there is no buffer overflow. - guarantee((size_t)(next - path) < max, "buffer overflow"); - // Terminate string. - *next = '\0'; -} - -// Verify that a found location matches the supplied path (without copying.) -bool ImageFileReader::verify_location(ImageLocation& location, const char* path) const { - // Manage the image string table. - ImageStrings strings(_string_bytes, _header.strings_size(_endian)); - // Position to first character of the path string. - const char* next = path; - // Get module name string. - const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings); - // If module string is not empty. - if (*module != '\0') { - // Compare '/module/' . - if (*next++ != '/') return false; - if (!(next = ImageStrings::starts_with(next, module))) return false; - if (*next++ != '/') return false; - } - // Get parent (package) string - const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings); - // If parent string is not empty string. - if (*parent != '\0') { - // Compare 'parent/' . - if (!(next = ImageStrings::starts_with(next, parent))) return false; - if (*next++ != '/') return false; - } - // Get base name string. - const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings); - // Compare with basne name. - if (!(next = ImageStrings::starts_with(next, base))) return false; - // Get extension string. - const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings); - // If extension is not empty. - if (*extension != '\0') { - // Compare '.extension' . - if (*next++ != '.') return false; - if (!(next = ImageStrings::starts_with(next, extension))) return false; - } - // True only if complete match and no more characters. - return *next == '\0'; -} - -// Return the resource data for the supplied location. -void ImageFileReader::get_resource(ImageLocation& location, u1* uncompressed_data) const { - // Retrieve the byte offset and size of the resource. - u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET); - u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED); - u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED); - if (compressed_size != 0) { - ResourceMark rm; - u1* compressed_data; - // If not memory mapped read in bytes. - if (!MemoryMapImage) { - // Allocate buffer for compression. - compressed_data = NEW_RESOURCE_ARRAY(u1, compressed_size); - // Read bytes from offset beyond the image index. - bool is_read = read_at(compressed_data, compressed_size, _index_size + offset); - guarantee(is_read, "error reading from image or short read"); - } else { - compressed_data = get_data_address() + offset; - } - // Get image string table. - const ImageStrings strings = get_strings(); - // Decompress resource. - ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, uncompressed_size, - &strings, false); - } else { - // Read bytes from offset beyond the image index. - bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset); - guarantee(is_read, "error reading from image or short read"); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/imageFile.hpp --- a/src/share/vm/classfile/imageFile.hpp Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,602 +0,0 @@ -/* - * Copyright (c) 2014, 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_VM_CLASSFILE_IMAGEFILE_HPP -#define SHARE_VM_CLASSFILE_IMAGEFILE_HPP - -#include "classfile/classLoader.hpp" -#include "memory/allocation.hpp" -#include "memory/allocation.inline.hpp" -#include "utilities/endian.hpp" -#include "utilities/globalDefinitions.hpp" -#include "utilities/growableArray.hpp" - -// Image files are an alternate file format for storing classes and resources. The -// goal is to supply file access which is faster and smaller than the jar format. -// It should be noted that unlike jars, information stored in an image is in native -// endian format. This allows the image to be mapped into memory without endian -// translation. This also means that images are platform dependent. -// -// Image files are structured as three sections; -// -// +-----------+ -// | Header | -// +-----------+ -// | | -// | Index | -// | | -// +-----------+ -// | | -// | | -// | Resources | -// | | -// | | -// +-----------+ -// -// The header contains information related to identification and description of -// contents. -// -// +-------------------------+ -// | Magic (0xCAFEDADA) | -// +------------+------------+ -// | Major Vers | Minor Vers | -// +------------+------------+ -// | Flags | -// +-------------------------+ -// | Resource Count | -// +-------------------------+ -// | Table Length | -// +-------------------------+ -// | Attributes Size | -// +-------------------------+ -// | Strings Size | -// +-------------------------+ -// -// Magic - means of identifying validity of the file. This avoids requiring a -// special file extension. -// Major vers, minor vers - differences in version numbers indicate structural -// changes in the image. -// Flags - various image wide flags (future). -// Resource count - number of resources in the file. -// Table length - the length of lookup tables used in the index. -// Attributes size - number of bytes in the region used to store location attribute -// streams. -// Strings size - the size of the region used to store strings used by the -// index and meta data. -// -// The index contains information related to resource lookup. The algorithm -// used for lookup is "A Practical Minimal Perfect Hashing Method" -// (http://homepages.dcc.ufmg.br/~nivio/papers/wea05.pdf). Given a path string -// in the form ///. return the resource location -// information; -// -// redirectIndex = hash(path, DEFAULT_SEED) % table_length; -// redirect = redirectTable[redirectIndex]; -// if (redirect == 0) return not found; -// locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % table_length; -// location = locationTable[locationIndex]; -// if (!verify(location, path)) return not found; -// return location; -// -// Note: The hash function takes an initial seed value. A different seed value -// usually returns a different result for strings that would otherwise collide with -// other seeds. The verify function guarantees the found resource location is -// indeed the resource we are looking for. -// -// The following is the format of the index; -// -// +-------------------+ -// | Redirect Table | -// +-------------------+ -// | Attribute Offsets | -// +-------------------+ -// | Attribute Data | -// +-------------------+ -// | Strings | -// +-------------------+ -// -// Redirect Table - Array of 32-bit signed values representing actions that -// should take place for hashed strings that map to that -// value. Negative values indicate no hash collision and can be -// quickly converted to indices into attribute offsets. Positive -// values represent a new seed for hashing an index into attribute -// offsets. Zero indicates not found. -// Attribute Offsets - Array of 32-bit unsigned values representing offsets into -// attribute data. Attribute offsets can be iterated to do a -// full survey of resources in the image. Offset of zero -// indicates no attributes. -// Attribute Data - Bytes representing compact attribute data for locations. (See -// comments in ImageLocation.) -// Strings - Collection of zero terminated UTF-8 strings used by the index and -// image meta data. Each string is accessed by offset. Each string is -// unique. Offset zero is reserved for the empty string. -// -// Note that the memory mapped index assumes 32 bit alignment of each component -// in the index. -// -// Endianness of an image. -// An image booted by hotspot is always in native endian. However, it is possible -// to read (by the JDK) in alternate endian format. Primarily, this is during -// cross platform scenarios. Ex, where javac needs to read an embedded image -// to access classes for crossing compilation. -// - -class ImageFileReader; // forward declaration - -// Manage image file string table. -class ImageStrings VALUE_OBJ_CLASS_SPEC { -private: - u1* _data; // Data bytes for strings. - u4 _size; // Number of bytes in the string table. -public: - enum { - // Not found result from find routine. - NOT_FOUND = -1, - // Prime used to generate hash for Perfect Hashing. - HASH_MULTIPLIER = 0x01000193 - }; - - ImageStrings(u1* data, u4 size) : _data(data), _size(size) {} - - // Return the UTF-8 string beginning at offset. - inline const char* get(u4 offset) const { - guarantee(offset < _size, "offset exceeds string table size"); - return (const char*)(_data + offset); - } - - // Compute the Perfect Hashing hash code for the supplied UTF-8 string. - inline static u4 hash_code(const char* string) { - return hash_code(string, HASH_MULTIPLIER); - } - - // Compute the Perfect Hashing hash code for the supplied string, starting at seed. - static s4 hash_code(const char* string, s4 seed); - - // Match up a string in a perfect hash table. Result still needs validation - // for precise match. - static s4 find(Endian* endian, const char* name, s4* redirect, u4 length); - - // Test to see if UTF-8 string begins with the start UTF-8 string. If so, - // return non-NULL address of remaining portion of string. Otherwise, return - // NULL. Used to test sections of a path without copying from image string - // table. - static const char* starts_with(const char* string, const char* start); - - // Test to see if UTF-8 string begins with start char. If so, return non-NULL - // address of remaining portion of string. Otherwise, return NULL. Used - // to test a character of a path without copying. - inline static const char* starts_with(const char* string, const char ch) { - return *string == ch ? string + 1 : NULL; - } -}; - -// Manage image file location attribute data. Within an image, a location's -// attributes are compressed into a stream of bytes. An attribute stream is -// composed of individual attribute sequences. Each attribute sequence begins with -// a header byte containing the attribute 'kind' (upper 5 bits of header) and the -// 'length' less 1 (lower 3 bits of header) of bytes that follow containing the -// attribute value. Attribute values present as most significant byte first. -// -// Ex. Container offset (ATTRIBUTE_OFFSET) 0x33562 would be represented as 0x22 -// (kind = 4, length = 3), 0x03, 0x35, 0x62. -// -// An attribute stream is terminated with a header kind of ATTRIBUTE_END (header -// byte of zero.) -// -// ImageLocation inflates the stream into individual values stored in the long -// array _attributes. This allows an attribute value can be quickly accessed by -// direct indexing. Unspecified values default to zero. -// -// Notes: -// - Even though ATTRIBUTE_END is used to mark the end of the attribute stream, -// streams will contain zero byte values to represent lesser significant bits. -// Thus, detecting a zero byte is not sufficient to detect the end of an attribute -// stream. -// - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region -// storing the resources. Thus, in an image this represents the number of bytes -// after the index. -// - Currently, compressed resources are represented by having a non-zero -// ATTRIBUTE_COMPRESSED value. This represents the number of bytes stored in the -// image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the -// inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value -// of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and -// in memory. In the future, additional compression techniques will be used and -// represented differently. -// - Package strings include trailing slash and extensions include prefix period. -// -class ImageLocation VALUE_OBJ_CLASS_SPEC { -public: - enum { - ATTRIBUTE_END, // End of attribute stream marker - ATTRIBUTE_MODULE, // String table offset of module name - ATTRIBUTE_PARENT, // String table offset of resource path parent - ATTRIBUTE_BASE, // String table offset of resource path base - ATTRIBUTE_EXTENSION, // String table offset of resource path extension - ATTRIBUTE_OFFSET, // Container byte offset of resource - ATTRIBUTE_COMPRESSED, // In image byte size of the compressed resource - ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource - ATTRIBUTE_COUNT // Number of attribute kinds - }; - -private: - // Values of inflated attributes. - u8 _attributes[ATTRIBUTE_COUNT]; - - // Return the attribute value number of bytes. - inline static u1 attribute_length(u1 data) { - return (data & 0x7) + 1; - } - - // Return the attribute kind. - inline static u1 attribute_kind(u1 data) { - u1 kind = data >> 3; - guarantee(kind < ATTRIBUTE_COUNT, "invalid attribute kind"); - return kind; - } - - // Return the attribute length. - inline static u8 attribute_value(u1* data, u1 n) { - guarantee(0 < n && n <= 8, "invalid attribute value length"); - u8 value = 0; - // Most significant bytes first. - for (u1 i = 0; i < n; i++) { - value <<= 8; - value |= data[i]; - } - return value; - } - -public: - ImageLocation() { - clear_data(); - } - - ImageLocation(u1* data) { - clear_data(); - set_data(data); - } - - // Inflates the attribute stream into individual values stored in the long - // array _attributes. This allows an attribute value to be quickly accessed by - // direct indexing. Unspecified values default to zero. - void set_data(u1* data); - - // Zero all attribute values. - void clear_data(); - - // Retrieve an attribute value from the inflated array. - inline u8 get_attribute(u1 kind) const { - guarantee(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT, "invalid attribute kind"); - return _attributes[kind]; - } - - // Retrieve an attribute string value from the inflated array. - inline const char* get_attribute(u4 kind, const ImageStrings& strings) const { - return strings.get((u4)get_attribute(kind)); - } -}; - -// -// NOTE: needs revision. -// Each loader requires set of module meta data to identify which modules and -// packages are managed by that loader. Currently, there is one image file per -// builtin loader, so only one module meta data resource per file. -// -// Each element in the module meta data is a native endian 4 byte integer. Note -// that entries with zero offsets for string table entries should be ignored ( -// padding for hash table lookup.) -// -// Format: -// Count of package to module entries -// Count of module to package entries -// Perfect Hash redirect table[Count of package to module entries] -// Package to module entries[Count of package to module entries] -// Offset to package name in string table -// Offset to module name in string table -// Perfect Hash redirect table[Count of module to package entries] -// Module to package entries[Count of module to package entries] -// Offset to module name in string table -// Count of packages in module -// Offset to first package in packages table -// Packages[] -// Offset to package name in string table -// -// Manage the image module meta data. -class ImageModuleData : public CHeapObj { - class Header VALUE_OBJ_CLASS_SPEC { - private: - u4 _ptm_count; // Count of package to module entries - u4 _mtp_count; // Count of module to package entries - public: - inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); } - inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); } - }; - - // Hashtable entry - class HashData VALUE_OBJ_CLASS_SPEC { - private: - u4 _name_offset; // Name offset in string table - public: - inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); } - }; - - // Package to module hashtable entry - class PTMData : public HashData { - private: - u4 _module_name_offset; // Module name offset in string table - public: - inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); } - }; - - // Module to package hashtable entry - class MTPData : public HashData { - private: - u4 _package_count; // Number of packages in module - u4 _package_offset; // Offset in package list - public: - inline u4 package_count(Endian* endian) const { return endian->get(_package_count); } - inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); } - }; - - const ImageFileReader* _image_file; // Source image file - Endian* _endian; // Endian handler - ImageStrings _strings; // Image file strings - u1* _data; // Module data resource data - u8 _data_size; // Size of resource data - Header* _header; // Module data header - s4* _ptm_redirect; // Package to module hashtable redirect - PTMData* _ptm_data; // Package to module data - s4* _mtp_redirect; // Module to packages hashtable redirect - MTPData* _mtp_data; // Module to packages data - s4* _mtp_packages; // Package data (name offsets) - - // Return a string from the string table. - inline const char* get_string(u4 offset) { - return _strings.get(offset); - } - - inline u4 mtp_package(u4 index) { - return _endian->get(_mtp_packages[index]); - } - -public: - ImageModuleData(const ImageFileReader* image_file, const char* module_data_name); - ~ImageModuleData(); - - // Return the name of the module data resource. - static void module_data_name(char* buffer, const char* image_file_name); - - // Return the module in which a package resides. Returns NULL if not found. - const char* package_to_module(const char* package_name); - - // Returns all the package names in a module. Returns NULL if module not found. - GrowableArray* module_to_packages(const char* module_name); -}; - -// Image file header, starting at offset 0. -class ImageHeader VALUE_OBJ_CLASS_SPEC { -private: - u4 _magic; // Image file marker - u4 _version; // Image file major version number - u4 _flags; // Image file flags - u4 _resource_count; // Number of resources in file - u4 _table_length; // Number of slots in index tables - u4 _locations_size; // Number of bytes in attribute table - u4 _strings_size; // Number of bytes in string table - -public: - u4 magic() const { return _magic; } - u4 magic(Endian* endian) const { return endian->get(_magic); } - void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); } - - u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; } - u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; } - void set_version(Endian* endian, u4 major_version, u4 minor_version) { - return endian->set(_version, major_version << 16 | minor_version); - } - - u4 flags(Endian* endian) const { return endian->get(_flags); } - void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); } - - u4 resource_count(Endian* endian) const { return endian->get(_resource_count); } - void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); } - - u4 table_length(Endian* endian) const { return endian->get(_table_length); } - void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); } - - u4 locations_size(Endian* endian) const { return endian->get(_locations_size); } - void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); } - - u4 strings_size(Endian* endian) const { return endian->get(_strings_size); } - void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); } -}; - -// Max path length limit independent of platform. Windows max path is 1024, -// other platforms use 4096. The JCK fails several tests when 1024 is used. -#define IMAGE_MAX_PATH 4096 - -// Manage the image file. -// ImageFileReader manages the content of an image file. -// Initially, the header of the image file is read for validation. If valid, -// values in the header are used calculate the size of the image index. The -// index is then memory mapped to allow load on demand and sharing. The -// -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.) -// An image can be used by Hotspot and multiple reference points in the JDK, thus -// it is desirable to share a reader. To accomodate sharing, a share table is -// defined (see ImageFileReaderTable in imageFile.cpp) To track the number of -// uses, ImageFileReader keeps a use count (_use). Use is incremented when -// 'opened' by reference point and decremented when 'closed'. Use of zero -// leads the ImageFileReader to be actually closed and discarded. -class ImageFileReader : public CHeapObj { -private: - // Manage a number of image files such that an image can be shared across - // multiple uses (ex. loader.) - static GrowableArray* _reader_table; - - char* _name; // Name of image - s4 _use; // Use count - int _fd; // File descriptor - Endian* _endian; // Endian handler - u8 _file_size; // File size in bytes - ImageHeader _header; // Image header - size_t _index_size; // Total size of index - u1* _index_data; // Raw index data - s4* _redirect_table; // Perfect hash redirect table - u4* _offsets_table; // Location offset table - u1* _location_bytes; // Location attributes - u1* _string_bytes; // String table - - ImageFileReader(const char* name, bool big_endian); - ~ImageFileReader(); - - // Compute number of bytes in image file index. - inline u8 index_size() { - return sizeof(ImageHeader) + - table_length() * sizeof(u4) * 2 + locations_size() + strings_size(); - } - -public: - enum { - // Image file marker. - IMAGE_MAGIC = 0xCAFEDADA, - // Endian inverted Image file marker. - IMAGE_MAGIC_INVERT = 0xDADAFECA, - // Image file major version number. - MAJOR_VERSION = 1, - // Image file minor version number. - MINOR_VERSION = 0 - }; - - // Open an image file, reuse structure if file already open. - static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian()); - - // Close an image file if the file is not in use elsewhere. - static void close(ImageFileReader *reader); - - // Return an id for the specifed ImageFileReader. - static u8 readerToID(ImageFileReader *reader); - - // Validate the image id. - static bool idCheck(u8 id); - - // Return an id for the specifed ImageFileReader. - static ImageFileReader* idToReader(u8 id); - - // Open image file for read access. - bool open(); - - // Close image file. - void close(); - - // Read directly from the file. - bool read_at(u1* data, u8 size, u8 offset) const; - - inline Endian* endian() const { return _endian; } - - // Retrieve name of image file. - inline const char* name() const { - return _name; - } - - // Retrieve size of image file. - inline u8 file_size() const { - return _file_size; - } - - // Return first address of index data. - inline u1* get_index_address() const { - return _index_data; - } - - // Return first address of resource data. - inline u1* get_data_address() const { - return _index_data + _index_size; - } - - // Get the size of the index data. - size_t get_index_size() const { - return _index_size; - } - - inline u4 table_length() const { - return _header.table_length(_endian); - } - - inline u4 locations_size() const { - return _header.locations_size(_endian); - } - - inline u4 strings_size()const { - return _header.strings_size(_endian); - } - - inline u4* offsets_table() const { - return _offsets_table; - } - - // Increment use count. - inline void inc_use() { - _use++; - } - - // Decrement use count. - inline bool dec_use() { - return --_use == 0; - } - - // Return a string table accessor. - inline const ImageStrings get_strings() const { - return ImageStrings(_string_bytes, _header.strings_size(_endian)); - } - - // Return location attribute stream at offset. - inline u1* get_location_offset_data(u4 offset) const { - guarantee((u4)offset < _header.locations_size(_endian), - "offset exceeds location attributes size"); - return offset != 0 ? _location_bytes + offset : NULL; - } - - // Return location attribute stream for location i. - inline u1* get_location_data(u4 index) const { - guarantee((u4)index < _header.table_length(_endian), - "index exceeds location count"); - u4 offset = _endian->get(_offsets_table[index]); - - return get_location_offset_data(offset); - } - - // Find the location attributes associated with the path. Returns true if - // the location is found, false otherwise. - bool find_location(const char* path, ImageLocation& location) const; - - // Assemble the location path. - void location_path(ImageLocation& location, char* path, size_t max) const; - - // Verify that a found location matches the supplied path. - bool verify_location(ImageLocation& location, const char* path) const; - - // Return the resource for the supplied path. - void get_resource(ImageLocation& location, u1* uncompressed_data) const; -}; -#endif // SHARE_VM_CLASSFILE_IMAGEFILE_HPP diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/classfile/jimage.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/classfile/jimage.hpp Fri Sep 04 10:12:08 2015 -0300 @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2015, 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 "jni.h" + +// Opaque reference to a JImage file. +class JImageFile; +// Opaque reference to an image file resource location. +typedef jlong JImageLocationRef; + +// Max path length limit independent of platform. Windows max path is 1024, +// other platforms use 4096. The JCK fails several tests when 1024 is used. +#define JIMAGE_MAX_PATH 4096 + +// JImage Error Codes + +// The image file is not prefixed with 0xCAFEDADA +#define JIMAGE_BAD_MAGIC (-1) +// The image file does not have a compatible (translatable) version +#define JIMAGE_BAD_VERSION (-2) +// The image file content is malformed +#define JIMAGE_CORRUPTED (-3) + +/* + * JImageOpen - Given the supplied full path file name, open an image file. This + * function will also initialize tables and retrieve meta-data necessary to + * satisfy other functions in the API. If the image file has been previously + * open, a new open request will share memory and resources used by the previous + * open. A call to JImageOpen should be balanced by a call to JImageClose, to + * release memory and resources used. If the image file is not found or cannot + * be open, then NULL is returned and error will contain a reason for the + * failure; a positive value for a system error number, negative for a jimage + * specific error (see JImage Error Codes.) + * + * Ex. + * jint error; + * JImageFile* jimage = (*JImageOpen)(JAVA_HOME "lib/modules/bootmodules.jimage", &error); + * if (image == NULL) { + * tty->print_cr("JImage failed to open: %d", error); + * ... + * } + * ... + */ + +extern "C" JImageFile* JIMAGE_Open(const char *name, jint* error); + +typedef JImageFile* (*JImageOpen_t)(const char *name, jint* error); + +/* + * JImageClose - Given the supplied open image file (see JImageOpen), release + * memory and resources used by the open file and close the file. If the image + * file is shared by other uses, release and close is deferred until the last use + * is also closed. + * + * Ex. + * (*JImageClose)(image); + */ + +extern "C" void JIMAGE_Close(JImageFile* jimage); + +typedef void (*JImageClose_t)(JImageFile* jimage); + + +/* + * JImagePackageToModule - Given an open image file (see JImageOpen) and the name + * of a package, return the name of module where the package resides. If the + * package does not exist in the image file, the function returns NULL. + * The resulting string does/should not have to be released. All strings are + * utf-8, zero byte terminated. + * + * Ex. + * const char* package = (*JImagePackageToModule)(image, "java/lang"); + * tty->print_cr(package); + * —> java.base + */ + +extern "C" const char * JIMAGE_PackageToModule(JImageFile* jimage, const char* package_name); + +typedef const char* (*JImagePackageToModule_t)(JImageFile* jimage, const char* package_name); + + +/* + * JImageFindResource - Given an open image file (see JImageOpen), a module + * name, a version string and the name of a class/resource, return location + * information describing the resource and its size. If no resource is found, the + * function returns JIMAGE_NOT_FOUND and the value of size is undefined. + * The version number should be "9.0" and is not used in locating the resource. + * The resulting location does/should not have to be released. + * All strings are utf-8, zero byte terminated. + * + * Ex. + * jlong size; + * JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size); + */ +extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* jimage, + const char* module_name, const char* version, const char* name, + jlong* size); + +typedef JImageLocationRef(*JImageFindResource_t)(JImageFile* jimage, + const char* module_name, const char* version, const char* name, + jlong* size); + + +/* + * JImageGetResource - Given an open image file (see JImageOpen), a resource’s + * location information (see JImageFindResource), a buffer of appropriate + * size and the size, retrieve the bytes associated with the + * resource. If the size is less than the resource size then the read is truncated. + * If the size is greater than the resource size then the remainder of the buffer + * is zero filled. The function will return the actual size of the resource. + * + * Ex. + * jlong size; + * JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size); + * char* buffer = new char[size]; + * (*JImageGetResource)(image, location, buffer, size); + */ +extern "C" jlong JIMAGE_GetResource(JImageFile* jimage, JImageLocationRef location, + char* buffer, jlong size); + +typedef jlong(*JImageGetResource_t)(JImageFile* jimage, JImageLocationRef location, + char* buffer, jlong size); + + +/* + * JImageResourceIterator - Given an open image file (see JImageOpen), a visitor + * function and a visitor argument, iterator through each of the image's resources. + * The visitor function is called with the image file, the module name, the + * package name, the base name, the extension and the visitor argument. The return + * value of the visitor function should be true, unless an early iteration exit is + * required. All strings are utf-8, zero byte terminated.file. + * + * Ex. + * bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) { + * if (strcmp(extension, “class”) == 0) { + * char path[JIMAGE_MAX_PATH]; + * Thread* THREAD = Thread::current(); + * jio_snprintf(path, JIMAGE_MAX_PATH - 1, "/%s/%s", package, name); + * ClassLoader::compile_the_world_in(path, (Handle)arg, THREAD); + * return !HAS_PENDING_EXCEPTION; + * } + * return true; + * } + * (*JImageResourceIterator)(image, ctw_visitor, loader); + */ + +typedef bool (*JImageResourceVisitor_t)(JImageFile* jimage, + const char* module_name, const char* version, const char* package, + const char* name, const char* extension, void* arg); + +extern "C" void JIMAGE_ResourceIterator(JImageFile* jimage, + JImageResourceVisitor_t visitor, void *arg); + +typedef void (*JImageResourceIterator_t)(JImageFile* jimage, + JImageResourceVisitor_t visitor, void* arg); diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/precompiled/precompiled.hpp --- a/src/share/vm/precompiled/precompiled.hpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/precompiled/precompiled.hpp Fri Sep 04 10:12:08 2015 -0300 @@ -57,8 +57,6 @@ # include "classfile/classFileParser.hpp" # include "classfile/classFileStream.hpp" # include "classfile/classLoader.hpp" -# include "classfile/imageDecompressor.hpp" -# include "classfile/imageFile.hpp" # include "classfile/javaClasses.hpp" # include "classfile/symbolTable.hpp" # include "classfile/systemDictionary.hpp" @@ -232,7 +230,6 @@ # include "utilities/constantTag.hpp" # include "utilities/copy.hpp" # include "utilities/debug.hpp" -# include "utilities/endian.hpp" # include "utilities/exceptions.hpp" # include "utilities/globalDefinitions.hpp" # include "utilities/growableArray.hpp" diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/prims/jvm.cpp Fri Sep 04 10:12:08 2015 -0300 @@ -24,8 +24,6 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" -#include "classfile/imageDecompressor.hpp" -#include "classfile/imageFile.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/stringTable.hpp" @@ -71,7 +69,6 @@ #include "utilities/copy.hpp" #include "utilities/defaultStream.hpp" #include "utilities/dtrace.hpp" -#include "utilities/endian.hpp" #include "utilities/events.hpp" #include "utilities/histogram.hpp" #include "utilities/macros.hpp" @@ -3668,244 +3665,3 @@ info->is_attachable = AttachListener::is_attach_supported(); } JVM_END - -// jdk.internal.jimage ///////////////////////////////////////////////////////// -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. - -// Java entry to open an image file for sharing. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jlong, -JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian)) { - JVMWrapper("JVM_ImageOpen"); - // Open image file for reading. - ImageFileReader* reader = ImageFileReader::open(nativePath, big_endian != JNI_FALSE); - // Return image ID as a jlong. - return ImageFileReader::readerToID(reader); -} -JVM_END - -// Java entry for closing a shared image file. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(void, -JVM_ImageClose(JNIEnv *env, jlong id)) { - JVMWrapper("JVM_ImageClose"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // If valid reader the close. - if (reader != NULL) { - ImageFileReader::close(reader); - } -} -JVM_END - -// Java entry for accessing the base address of the image index. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jlong, -JVM_ImageGetIndexAddress(JNIEnv *env, jlong id)) { - JVMWrapper("JVM_ImageGetIndexAddress"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // If valid reader return index base address (as jlong) else zero. - return reader != NULL ? (jlong)reader->get_index_address() : 0L; -} -JVM_END - -// Java entry for accessing the base address of the image data. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jlong, -JVM_ImageGetDataAddress(JNIEnv *env, jlong id)) { - JVMWrapper("JVM_ImageGetDataAddress"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // If valid reader return data base address (as jlong) else zero. - return MemoryMapImage && reader != NULL ? (jlong)reader->get_data_address() : 0L; -} -JVM_END - -// Java entry for reading an uncompressed resource from the image. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jboolean, -JVM_ImageRead(JNIEnv *env, jlong id, jlong offset, - unsigned char* uncompressedAddress, jlong uncompressed_size)) { - JVMWrapper("JVM_ImageRead"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id);\ - // If not a valid reader the fail the read. - if (reader == NULL) return false; - // Get the file offset of resource data. - u8 file_offset = reader->get_index_size() + offset; - // Check validity of arguments. - if (offset < 0 || - uncompressed_size < 0 || - file_offset > reader->file_size() - uncompressed_size) { - return false; - } - // Read file content into buffer. - return (jboolean)reader->read_at((u1*)uncompressedAddress, uncompressed_size, - file_offset); -} -JVM_END - -// Java entry for reading a compressed resource from the image. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jboolean, -JVM_ImageReadCompressed(JNIEnv *env, - jlong id, jlong offset, - unsigned char* compressedAddress, jlong compressed_size, - unsigned char* uncompressedAddress, jlong uncompressed_size)) { - JVMWrapper("JVM_ImageReadCompressed"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // If not a valid reader the fail the read. - if (reader == NULL) return false; - // Get the file offset of resource data. - u8 file_offset = reader->get_index_size() + offset; - // Check validity of arguments. - if (offset < 0 || - compressed_size < 0 || - uncompressed_size < 0 || - file_offset > reader->file_size() - compressed_size) { - return false; - } - - // Read file content into buffer. - bool is_read = reader->read_at(compressedAddress, compressed_size, - file_offset); - // If successfully read then decompress. - if (is_read) { - const ImageStrings strings = reader->get_strings(); - ImageDecompressor::decompress_resource(compressedAddress, uncompressedAddress, - uncompressed_size, &strings, true); - } - return (jboolean)is_read; -} -JVM_END - -// Java entry for retrieving UTF-8 bytes from image string table. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(const char*, JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset)) { - JVMWrapper("JVM_ImageGetStringBytes"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // Fail if not valid reader. - if (reader == NULL) return NULL; - // Manage image string table. - ImageStrings strings = reader->get_strings(); - // Retrieve string adrress from table. - const char* data = strings.get(offset); - return data; -} -JVM_END - -// Utility function to copy location information into a jlong array. -// WARNING: This function is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -static void image_expand_location(JNIEnv *env, jlong* rawAttributes, ImageLocation& location) { - // Copy attributes from location. - for (int kind = ImageLocation::ATTRIBUTE_END + 1; - kind < ImageLocation::ATTRIBUTE_COUNT; - kind++) { - rawAttributes[kind] = location.get_attribute(kind); - } -} - -// Java entry for retrieving location attributes for attribute offset. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jlong*, JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset)) { - JVMWrapper("JVM_ImageGetAttributes"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // Fail if not valid reader. - if (reader == NULL) return NULL; - // Retrieve first byte address of resource's location attribute stream. - u1* data = reader->get_location_offset_data(offset); - // Fail if not valid offset. - if (data == NULL) return NULL; - // Expand stream into array. - ImageLocation location(data); - image_expand_location(env, rawAttributes, location); - return rawAttributes; -} -JVM_END - -// Java entry for retrieving location attributes count for attribute offset. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jsize, JVM_ImageGetAttributesCount(JNIEnv *env)) { - JVMWrapper("JVM_ImageGetAttributesCount"); - return ImageLocation::ATTRIBUTE_COUNT; -} -JVM_END - -// Java entry for retrieving location attributes for named resource. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jlong*, -JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id)) { - JVMWrapper("JVM_ImageFindAttributes"); - // Mark for temporary buffers. - ResourceMark rm; - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // Fail if not valid reader. - if (reader == NULL) return NULL; - // Convert byte array to a cstring. - char* path = NEW_RESOURCE_ARRAY(char, size + 1); - memcpy(path, rawBytes, size); - path[size] = '\0'; - // Locate resource location data. - ImageLocation location; - bool found = reader->find_location(path, location); - // Resource not found. - if (!found) return NULL; - // Expand stream into array. - image_expand_location(env, rawAttributes, location); - return rawAttributes; -} -JVM_END - -// Java entry for retrieving all the attribute stream offsets from an image. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(jint*, JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id)) { - JVMWrapper("JVM_ImageAttributeOffsets"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // Fail if not valid reader. - if (reader == NULL) return NULL; - // Determine endian for reader. - Endian* endian = reader->endian(); - // Get base address of attribute stream offsets table. - u4* offsets_table = reader->offsets_table(); - // Allocate int array result. - // Copy values to result (converting endian.) - for (u4 i = 0; i < length; i++) { - rawOffsets[i] = endian->get(offsets_table[i]); - } - return rawOffsets; -} -JVM_END - -// Java entry for retrieving all the attribute stream offsets length from an image. -// WARNING: This API is experimental and temporary during JDK 9 development -// cycle. It will not be supported in the eventual JDK 9 release. -JVM_ENTRY(unsigned int, JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id)) { - JVMWrapper("JVM_ImageAttributeOffsetsLength"); - // Convert image ID to image reader structure. - ImageFileReader* reader = ImageFileReader::idToReader(id); - // Fail if not valid reader. - if (reader == NULL) return 0; - // Get perfect hash table length. - u4 length = reader->table_length(); - return (jint) length; -} -JVM_END diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/prims/jvm.h --- a/src/share/vm/prims/jvm.h Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/prims/jvm.h Fri Sep 04 10:12:08 2015 -0300 @@ -571,52 +571,6 @@ JNIEXPORT jboolean JNICALL JVM_SupportsCX8(void); -/* - * jdk.internal.jimage - * WARNING: This API is experimental and temporary during JDK 9 development - * cycle. It will not be supported in the eventual JDK 9 release. - */ - -JNIEXPORT jlong JNICALL -JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian); - -JNIEXPORT void JNICALL -JVM_ImageClose(JNIEnv *env, jlong id); - -JNIEXPORT jlong JNICALL -JVM_ImageGetIndexAddress(JNIEnv *env, jlong id); - -JNIEXPORT jlong JNICALL -JVM_ImageGetDataAddress(JNIEnv *env,jlong id); - -JNIEXPORT jboolean JNICALL -JVM_ImageRead(JNIEnv *env, jlong id, jlong offset, - unsigned char* uncompressedAddress, jlong uncompressed_size); - - -JNIEXPORT jboolean JNICALL -JVM_ImageReadCompressed(JNIEnv *env, jlong id, jlong offset, - unsigned char* compressedBuffer, jlong compressed_size, - unsigned char* uncompressedBuffer, jlong uncompressed_size); - -JNIEXPORT const char* JNICALL -JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset); - -JNIEXPORT jlong* JNICALL -JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset); - -JNIEXPORT jsize JNICALL -JVM_ImageGetAttributesCount(JNIEnv *env); - -JNIEXPORT jlong* JNICALL -JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id); - -JNIEXPORT jint* JNICALL -JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id); - -JNIEXPORT unsigned int JNICALL -JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id); - /************************************************************************* PART 2: Support for the Verifier and Class File Format Checker ************************************************************************/ diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/prims/whitebox.cpp --- a/src/share/vm/prims/whitebox.cpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/prims/whitebox.cpp Fri Sep 04 10:12:08 2015 -0300 @@ -27,7 +27,6 @@ #include #include "classfile/classLoaderData.hpp" -#include "classfile/imageFile.hpp" #include "classfile/stringTable.hpp" #include "code/codeCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" @@ -1144,131 +1143,7 @@ return (jlong) MetaspaceGC::capacity_until_GC(); WB_END -WB_ENTRY(jboolean, WB_ReadImageFile(JNIEnv* env, jobject wb, jstring imagefile)) - const char* filename = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(imagefile)); - return ImageFileReader::open(filename) != NULL; -WB_END -WB_ENTRY(jlong, WB_imageOpenImage(JNIEnv *env, jobject wb, jstring path, jboolean big_endian)) - ThreadToNativeFromVM ttn(thread); - const char *nativePath = env->GetStringUTFChars(path, NULL); - jlong ret = JVM_ImageOpen(env, nativePath, big_endian); - - env->ReleaseStringUTFChars(path, nativePath); - return ret; -WB_END - -WB_ENTRY(void, WB_imageCloseImage(JNIEnv *env, jobject wb, jlong id)) - ThreadToNativeFromVM ttn(thread); - JVM_ImageClose(env, id); -WB_END - -WB_ENTRY(jlong, WB_imageGetIndexAddress(JNIEnv *env, jobject wb, jlong id)) - ThreadToNativeFromVM ttn(thread); - return JVM_ImageGetIndexAddress(env, id); -WB_END - -WB_ENTRY(jlong, WB_imageGetDataAddress(JNIEnv *env, jobject wb, jlong id)) - ThreadToNativeFromVM ttn(thread); - return JVM_ImageGetDataAddress(env, id); -WB_END - -WB_ENTRY(jboolean, WB_imageRead(JNIEnv *env, jobject wb, jlong id, jlong offset, jobject uncompressedBuffer, jlong uncompressed_size)) - ThreadToNativeFromVM ttn(thread); - if (uncompressedBuffer == NULL) { - return JNI_FALSE; - } - unsigned char* uncompressedAddress = - (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer); - return JVM_ImageRead(env, id, offset, uncompressedAddress, uncompressed_size); -WB_END - -WB_ENTRY(jboolean, WB_imageReadCompressed(JNIEnv *env, jobject wb, jlong id, jlong offset, jobject compressedBuffer, jlong compressed_size, jobject uncompressedBuffer, jlong uncompressed_size)) - ThreadToNativeFromVM ttn(thread); - if (uncompressedBuffer == NULL || compressedBuffer == NULL) { - return false; - } - // Get address of read direct buffer. - unsigned char* compressedAddress = - (unsigned char*) env->GetDirectBufferAddress(compressedBuffer); - // Get address of decompression direct buffer. - unsigned char* uncompressedAddress = - (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer); - return JVM_ImageReadCompressed(env, id, offset, compressedAddress, compressed_size, uncompressedAddress, uncompressed_size); -WB_END - -WB_ENTRY(jbyteArray, WB_imageGetStringBytes(JNIEnv *env, jobject wb, jlong id, jlong offset)) - ThreadToNativeFromVM ttn(thread); - const char* data = JVM_ImageGetStringBytes(env, id, offset); - // Determine String length. - size_t size = strlen(data); - // Allocate byte array. - jbyteArray byteArray = env->NewByteArray((jsize) size); - // Get array base address. - jbyte* rawBytes = env->GetByteArrayElements(byteArray, NULL); - // Copy bytes from image string table. - memcpy(rawBytes, data, size); - // Release byte array base address. - env->ReleaseByteArrayElements(byteArray, rawBytes, 0); - return byteArray; -WB_END - -WB_ENTRY(jlong, WB_imageGetStringsSize(JNIEnv *env, jobject wb, jlong id)) - ImageFileReader* reader = ImageFileReader::idToReader(id); - return reader? reader->strings_size() : 0L; -WB_END - -WB_ENTRY(jlongArray, WB_imageGetAttributes(JNIEnv *env, jobject wb, jlong id, jint offset)) - ThreadToNativeFromVM ttn(thread); - // Allocate a jlong large enough for all location attributes. - jlongArray attributes = env->NewLongArray(JVM_ImageGetAttributesCount(env)); - // Get base address for jlong array. - jlong* rawAttributes = env->GetLongArrayElements(attributes, NULL); - jlong* ret = JVM_ImageGetAttributes(env, rawAttributes, id, offset); - // Release jlong array base address. - env->ReleaseLongArrayElements(attributes, rawAttributes, 0); - return ret == NULL ? NULL : attributes; -WB_END - -WB_ENTRY(jlongArray, WB_imageFindAttributes(JNIEnv *env, jobject wb, jlong id, jbyteArray utf8)) - ThreadToNativeFromVM ttn(thread); - // Allocate a jlong large enough for all location attributes. - jlongArray attributes = env->NewLongArray(JVM_ImageGetAttributesCount(env)); - // Get base address for jlong array. - jlong* rawAttributes = env->GetLongArrayElements(attributes, NULL); - jsize size = env->GetArrayLength(utf8); - jbyte* rawBytes = env->GetByteArrayElements(utf8, NULL); - jlong* ret = JVM_ImageFindAttributes(env, rawAttributes, rawBytes, size, id); - env->ReleaseByteArrayElements(utf8, rawBytes, 0); - env->ReleaseLongArrayElements(attributes, rawAttributes, 0); - return ret == NULL ? NULL : attributes; -WB_END - -WB_ENTRY(jintArray, WB_imageAttributeOffsets(JNIEnv *env, jobject wb, jlong id)) - ThreadToNativeFromVM ttn(thread); - unsigned int length = JVM_ImageAttributeOffsetsLength(env, id); - if (length == 0) { - return NULL; - } - jintArray offsets = env->NewIntArray(length); - // Get base address of result. - jint* rawOffsets = env->GetIntArrayElements(offsets, NULL); - jint* ret = JVM_ImageAttributeOffsets(env, rawOffsets, length, id); - // Release result base address. - env->ReleaseIntArrayElements(offsets, rawOffsets, 0); - return ret == NULL ? NULL : offsets; -WB_END - -WB_ENTRY(jint, WB_imageGetIntAtAddress(JNIEnv *env, jobject wb, jlong address, jint offset, jboolean big_endian)) - unsigned char* arr = (unsigned char*) address + offset; - jint uraw; - if (big_endian) { - uraw = arr[0] << 24 | arr[1]<<16 | (arr[2]<<8) | arr[3]; - } else { - uraw = arr[0] | arr[1]<<8 | (arr[2]<<16) | arr[3]<<24; - } - return uraw; -WB_END WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue)) Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ? @@ -1576,21 +1451,6 @@ {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob }, {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, - {CC"readImageFile", CC"(Ljava/lang/String;)Z", (void*)&WB_ReadImageFile }, - {CC"imageOpenImage", CC"(Ljava/lang/String;Z)J",(void*)&WB_imageOpenImage }, - {CC"imageCloseImage", CC"(J)V", (void*)&WB_imageCloseImage }, - {CC"imageGetIndexAddress",CC"(J)J", (void*)&WB_imageGetIndexAddress}, - {CC"imageGetDataAddress",CC"(J)J", (void*)&WB_imageGetDataAddress}, - {CC"imageRead", CC"(JJLjava/nio/ByteBuffer;J)Z", - (void*)&WB_imageRead }, - {CC"imageReadCompressed",CC"(JJLjava/nio/ByteBuffer;JLjava/nio/ByteBuffer;J)Z", - (void*)&WB_imageReadCompressed}, - {CC"imageGetStringBytes",CC"(JI)[B", (void*)&WB_imageGetStringBytes}, - {CC"imageGetStringsSize",CC"(J)J", (void*)&WB_imageGetStringsSize}, - {CC"imageGetAttributes", CC"(JI)[J", (void*)&WB_imageGetAttributes}, - {CC"imageFindAttributes",CC"(J[B)[J", (void*)&WB_imageFindAttributes}, - {CC"imageAttributeOffsets",CC"(J)[I", (void*)&WB_imageAttributeOffsets}, - {CC"imageGetIntAtAddress",CC"(JIZ)I", (void*)&WB_imageGetIntAtAddress}, {CC"assertMatchingSafepointCalls", CC"(ZZ)V", (void*)&WB_AssertMatchingSafepointCalls }, {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated }, {CC"forceSafepoint", CC"()V", (void*)&WB_ForceSafepoint }, diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/runtime/arguments.cpp Fri Sep 04 10:12:08 2015 -0300 @@ -1591,9 +1591,6 @@ #endif // _LP64 #endif // !ZERO - // Set up runtime image flags. - set_runtime_image_flags(); - CodeCacheExtensions::set_ergonomics_flags(); } @@ -1848,16 +1845,6 @@ } } - // Set up runtime image flags -void Arguments::set_runtime_image_flags() { -#ifdef _LP64 - // Memory map image file by default on 64 bit machines. - if (FLAG_IS_DEFAULT(MemoryMapImage)) { - FLAG_SET_ERGO(bool, MemoryMapImage, true); - } -#endif -} - // This must be called after ergonomics. void Arguments::set_bytecode_flags() { if (!RewriteBytecodes) { diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/runtime/arguments.hpp --- a/src/share/vm/runtime/arguments.hpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/runtime/arguments.hpp Fri Sep 04 10:12:08 2015 -0300 @@ -346,8 +346,6 @@ static julong limit_by_allocatable_memory(julong size); // Setup heap size static void set_heap_size(); - // Set up runtime image flags - static void set_runtime_image_flags(); // Based on automatic selection criteria, should the // low pause collector be used. static bool should_auto_select_low_pause_collector(); diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/runtime/globals.hpp Fri Sep 04 10:12:08 2015 -0300 @@ -1087,9 +1087,6 @@ product(bool, AlwaysRestoreFPU, false, \ "Restore the FPU control word after every JNI call (expensive)") \ \ - product(bool, MemoryMapImage, false, \ - "Memory map entire runtime image") \ - \ diagnostic(bool, PrintCompilation2, false, \ "Print additional statistics per compilation") \ \ diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/runtime/init.cpp --- a/src/share/vm/runtime/init.cpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/runtime/init.cpp Fri Sep 04 10:12:08 2015 -0300 @@ -83,7 +83,6 @@ // during VM shutdown void perfMemory_exit(); void ostream_exit(); -bool image_decompressor_init(); void vm_init_globals() { check_ThreadShadow(); @@ -122,9 +121,6 @@ templateTable_init(); InterfaceSupport_init(); SharedRuntime::generate_stubs(); - if (!image_decompressor_init()) { - return JNI_ERR; - } universe2_init(); // dependent on codeCache_init and stubRoutines_init1 referenceProcessor_init(); jni_handles_init(); diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/runtime/mutexLocker.cpp --- a/src/share/vm/runtime/mutexLocker.cpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/runtime/mutexLocker.cpp Fri Sep 04 10:12:08 2015 -0300 @@ -100,7 +100,6 @@ Mutex* ExceptionCache_lock = NULL; Monitor* ObjAllocPost_lock = NULL; Mutex* OsrList_lock = NULL; -Mutex* ImageFileReaderTable_lock = NULL; #ifndef PRODUCT Mutex* FullGCALot_lock = NULL; @@ -228,7 +227,6 @@ def(ProfilePrint_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing def(ExceptionCache_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // serial profile printing def(OsrList_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); - def(ImageFileReaderTable_lock , Mutex , nonleaf, false, Monitor::_safepoint_check_always); // synchronize image readers open/close def(Debug1_lock , Mutex , leaf, true, Monitor::_safepoint_check_never); #ifndef PRODUCT def(FullGCALot_lock , Mutex , leaf, false, Monitor::_safepoint_check_always); // a lock to make FullGCALot MT safe diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/runtime/mutexLocker.hpp --- a/src/share/vm/runtime/mutexLocker.hpp Fri Sep 04 09:47:35 2015 +0200 +++ b/src/share/vm/runtime/mutexLocker.hpp Fri Sep 04 10:12:08 2015 -0300 @@ -102,7 +102,6 @@ extern Mutex* ProfilePrint_lock; // a lock used to serialize the printing of profiles extern Mutex* ExceptionCache_lock; // a lock used to synchronize exception cache updates extern Mutex* OsrList_lock; // a lock used to serialize access to OSR queues -extern Mutex* ImageFileReaderTable_lock; // a lock used to synchronize image readers open/close #ifndef PRODUCT extern Mutex* FullGCALot_lock; // a lock to make FullGCALot MT safe diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/utilities/endian.cpp --- a/src/share/vm/utilities/endian.cpp Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2015, 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 "utilities/endian.hpp" -#include "utilities/bytes.hpp" - -#ifndef bswap_16 -extern "C" inline u2 bswap_16(u2 x) { - return ((x & 0xFF) << 8) | - ((x >> 8) & 0xFF); -} -#endif - -#ifndef bswap_32 -extern "C" inline u4 bswap_32(u4 x) { - return ((x & 0xFF) << 24) | - ((x & 0xFF00) << 8) | - ((x >> 8) & 0xFF00) | - ((x >> 24) & 0xFF); -} -#endif - -#ifndef bswap_64 -extern "C" inline u8 bswap_64(u8 x) { - return (u8)bswap_32((u4)x) << 32 | - (u8)bswap_32((u4)(x >> 32)); -} -#endif - -u2 NativeEndian::get(u2 x) { return x; } -u4 NativeEndian::get(u4 x) { return x; } -u8 NativeEndian::get(u8 x) { return x; } -s2 NativeEndian::get(s2 x) { return x; } -s4 NativeEndian::get(s4 x) { return x; } -s8 NativeEndian::get(s8 x) { return x; } - -void NativeEndian::set(u2& x, u2 y) { x = y; } -void NativeEndian::set(u4& x, u4 y) { x = y; } -void NativeEndian::set(u8& x, u8 y) { x = y; } -void NativeEndian::set(s2& x, s2 y) { x = y; } -void NativeEndian::set(s4& x, s4 y) { x = y; } -void NativeEndian::set(s8& x, s8 y) { x = y; } - -NativeEndian NativeEndian::_native; - -u2 SwappingEndian::get(u2 x) { return bswap_16(x); } -u4 SwappingEndian::get(u4 x) { return bswap_32(x); } -u8 SwappingEndian::get(u8 x) { return bswap_64(x); } -s2 SwappingEndian::get(s2 x) { return bswap_16(x); } -s4 SwappingEndian::get(s4 x) { return bswap_32(x); } -s8 SwappingEndian::get(s8 x) { return bswap_64(x); } - -void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); } -void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); } -void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); } -void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); } -void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); } -void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); } - -SwappingEndian SwappingEndian::_swapping; - -Endian* Endian::get_handler(bool big_endian) { - // If requesting little endian on a little endian machine or - // big endian on a big endian machine use native handler - if (big_endian == is_big_endian()) { - return NativeEndian::get_native(); - } else { - // Use swapping handler. - return SwappingEndian::get_swapping(); - } -} - -Endian* Endian::get_native_handler() { - return NativeEndian::get_native(); -} diff -r ceb9d9044fc8 -r 262b86c271b0 src/share/vm/utilities/endian.hpp --- a/src/share/vm/utilities/endian.hpp Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2015, 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_VM_UTILITIES_ENDIAN_HPP -#define SHARE_VM_UTILITIES_ENDIAN_HPP - -#include "utilities/globalDefinitions.hpp" - -// Selectable endian handling. Endian handlers are used when accessing values -// that are of unknown (until runtime) endian. The only requirement of the values -// accessed are that they are aligned to proper size boundaries (no misalignment.) -// To select an endian handler, one should call Endian::get_handler(big_endian); -// Where big_endian is true if big endian is required and false otherwise. The -// native endian handler can be fetched with Endian::get_native_handler(); -// To retrieve a value using the approprate endian, use one of the overloaded -// calls to get. To set a value, then use one of the overloaded set calls. -// Ex. -// s4 value; // Imported value; -// ... -// Endian* endian = Endian::get_handler(true); // Use big endian -// s4 corrected = endian->get(value); -// endian->set(value, 1); -// -class Endian { -public: - virtual u2 get(u2 x) = 0; - virtual u4 get(u4 x) = 0; - virtual u8 get(u8 x) = 0; - virtual s2 get(s2 x) = 0; - virtual s4 get(s4 x) = 0; - virtual s8 get(s8 x) = 0; - - virtual void set(u2& x, u2 y) = 0; - virtual void set(u4& x, u4 y) = 0; - virtual void set(u8& x, u8 y) = 0; - virtual void set(s2& x, s2 y) = 0; - virtual void set(s4& x, s4 y) = 0; - virtual void set(s8& x, s8 y) = 0; - - // Quick little endian test. - static bool is_little_endian() { u4 x = 1; return *(u1 *)&x != 0; } - - // Quick big endian test. - static bool is_big_endian() { return !is_little_endian(); } - - // Select an appropriate endian handler. - static Endian* get_handler(bool big_endian); - - // Return the native endian handler. - static Endian* get_native_handler(); -}; - -// Normal endian handling. -class NativeEndian : public Endian { -private: - static NativeEndian _native; - -public: - u2 get(u2 x); - u4 get(u4 x); - u8 get(u8 x); - s2 get(s2 x); - s4 get(s4 x); - s8 get(s8 x); - - void set(u2& x, u2 y); - void set(u4& x, u4 y); - void set(u8& x, u8 y); - void set(s2& x, s2 y); - void set(s4& x, s4 y); - void set(s8& x, s8 y); - - static Endian* get_native() { return &_native; } -}; - -// Swapping endian handling. -class SwappingEndian : public Endian { -private: - static SwappingEndian _swapping; - -public: - u2 get(u2 x); - u4 get(u4 x); - u8 get(u8 x); - s2 get(s2 x); - s4 get(s4 x); - s8 get(s8 x); - - void set(u2& x, u2 y); - void set(u4& x, u4 y); - void set(u8& x, u8 y); - void set(s2& x, s2 y); - void set(s4& x, s4 y); - void set(s8& x, s8 y); - - static Endian* get_swapping() { return &_swapping; } -}; -#endif // SHARE_VM_UTILITIES_ENDIAN_HPP diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageAttributeOffsetsTest.java --- a/test/runtime/modules/ImageFile/ImageAttributeOffsetsTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Retrieves the array of offsets once with MemoryMapImage enabled once disabled. - * @test ImageAttributeOffsetsTest - * @summary Unit test for JVM_ImageAttributeOffsets() method - * @library /testlibrary /../../test/lib - * @build ImageAttributeOffsetsTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageAttributeOffsetsTest - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageAttributeOffsetsTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageAttributeOffsetsTest { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = wb.imageOpenImage(imageFile, bigEndian); - boolean passed = true; - // Get offsets - int[] array = wb.imageAttributeOffsets(id); - assertNotNull(array, "Could not retrieve offsets of array"); - - wb.imageCloseImage(id); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageCloseTest.java --- a/test/runtime/modules/ImageFile/ImageCloseTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test closing image opened multiple time. Test closing mutiple time an image. - * @test ImageCloseTest - * @summary Unit test for JVM_ImageClose() method - * @library /testlibrary /../../test/lib - * @build ImageCloseTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageCloseTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; - -public class ImageCloseTest { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = 0; - - // too many opens - for (int i = 0; i < 100; i++) { - id = wb.imageOpenImage(imageFile, bigEndian); - } - wb.imageCloseImage(id); - - // too many closes - id = wb.imageOpenImage(imageFile, bigEndian); - for (int i = 0; i < 100; i++) { - wb.imageCloseImage(id); - } - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageFileHeaderTest.java --- a/test/runtime/modules/ImageFile/ImageFileHeaderTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test that opening image containing wrong headers fails. - * @test ImageFileHeaderTest - * @library /testlibrary /../../test/lib - * @build ImageFileHeaderTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageFileHeaderTest - */ - -import java.nio.*; -import java.nio.file.Files; -import java.nio.file.Paths; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageFileHeaderTest { - - public static final int MAGIC = 0xCAFEDADA; - public static final short MAJOR = 0; - public static final short MINOR = 1; - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - public static ByteBuffer buf; - - public static void main(String... args) throws Exception { - - ByteOrder endian = getEndian(); - - // Try to read a non-existing file - assertFalse(wb.readImageFile("bogus")); - - // Incomplete header, only include the correct magic - buf = ByteBuffer.allocate(100); - buf.order(endian); - buf.putInt(MAGIC); - assertFalse(testImageFile("invalidheader.jimage")); - - // Build a complete header but reverse the endian - buf = ByteBuffer.allocate(100); - buf.order(endian == ByteOrder.LITTLE_ENDIAN ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN); - buf.putInt(MAGIC); - buf.putShort(MAJOR); - buf.putShort(MINOR); - assertFalse(testImageFile("wrongendian.jimage")); - - // Use the wrong magic - buf = ByteBuffer.allocate(100); - buf.order(endian); - buf.putInt(0xBEEFCACE); - buf.putShort(MAJOR); - buf.putShort(MINOR); - assertFalse(testImageFile("wrongmagic.jimage")); - - // Wrong major version (current + 1) - buf = ByteBuffer.allocate(100); - buf.order(endian); - buf.putInt(MAGIC); - buf.putShort((short)(MAJOR + 1)); - buf.putShort((short)MINOR); - assertFalse(testImageFile("wrongmajorversion.jimage")); - - // Wrong major version (negative) - buf = ByteBuffer.allocate(100); - buf.order(endian); - buf.putInt(MAGIC); - buf.putShort((short) -17); - buf.putShort((short)MINOR); - assertFalse(testImageFile("negativemajorversion.jimage")); - - // Wrong minor version (current + 1) - buf = ByteBuffer.allocate(100); - buf.order(endian); - buf.putInt(MAGIC); - buf.putShort((short)MAJOR); - buf.putShort((short)(MINOR + 1)); - assertFalse(testImageFile("wrongminorversion.jimage")); - - // Wrong minor version (negative) - buf = ByteBuffer.allocate(100); - buf.order(endian); - buf.putInt(MAGIC); - buf.putShort((short)MAJOR); - buf.putShort((short) -17); - assertFalse(testImageFile("negativeminorversion.jimage")); - } - - public static boolean testImageFile(String filename) throws Exception { - Files.write(Paths.get(filename), buf.array()); - System.out.println("Calling ReadImageFile on " + filename); - return wb.readImageFile(filename); - } - - public static ByteOrder getEndian() { - String endian = System.getProperty("sun.cpu.endian"); - if (endian.equalsIgnoreCase("little")) { - return ByteOrder.LITTLE_ENDIAN; - } else if (endian.equalsIgnoreCase("big")) { - return ByteOrder.BIG_ENDIAN; - } - throw new RuntimeException("Unexpected sun.cpu.endian value: " + endian); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageFindAttributesTest.java --- a/test/runtime/modules/ImageFile/ImageFindAttributesTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Find the attributes of existing and invalid classes. - * @test ImageFindAttributesTest - * @summary Unit test for JVM_ImageFindAttributes() method - * @library /testlibrary /../../test/lib - * @build ImageFindAttributesTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageFindAttributesTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageFindAttributesTest { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = wb.imageOpenImage(imageFile, bigEndian); - - // class resource - String className = "/java.base/java/lang/String.class"; - long[] longArr = wb.imageFindAttributes(id, className.getBytes()); - - assertNotNull(longArr, "Could not retrieve attributes of class " + className); - - // non-existent resource - String neClassName = "/java.base/java/lang/NonExistentClass.class"; - longArr = wb.imageFindAttributes(id, neClassName.getBytes()); - - assertNull(longArr, "Failed. Returned not null for non-existent " + neClassName); - - // garbage byte array - byte[] buf = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - longArr = wb.imageFindAttributes(id, buf); - - assertNull(longArr, "Found attributes for garbage class"); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageGetAttributesTest.java --- a/test/runtime/modules/ImageFile/ImageGetAttributesTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test getting all attributes, - * @test ImageGetAttributesTest - * @summary Unit test for JVM_ImageGetAttributes() method - * @library /testlibrary /../../test/lib - * @build LocationConstants ImageGetAttributesTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetAttributesTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageGetAttributesTest implements LocationConstants { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - testImageGetAttributes(imageFile); - } - - private static void testImageGetAttributes(String imageFile) { - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = wb.imageOpenImage(imageFile, bigEndian); - try { - long stringsSize = wb.imageGetStringsSize(id); - assertNE(stringsSize, 0, "strings size is 0"); - - int[] array = wb.imageAttributeOffsets(id); - assertNotNull(array, "Could not retrieve offsets of array"); - - // Get non-null attributes - boolean attFound = false; - int[] idx = {-1, -1, -1}; - // first non-null attribute - for (int i = 0; i < array.length; i++) { - if (array[i] != 0) { - attFound = true; - idx[0] = i; - break; - } - } - - // middle non-null attribute - for (int i = array.length / 2; i < array.length; i++) { - if (array[i] != 0) { - attFound = true; - idx[1] = i; - break; - } - } - - // last non-null attribute - for (int i = array.length - 1; i >= 0; i--) { - if (array[i] != 0) { - attFound = true; - idx[2] = i; - break; - } - } - assertTrue(attFound, "Failed. No non-null offset attributes"); - // test cases above - for (int i = 0; i < 3; i++) { - if (idx[i] != -1) { - long[] attrs = wb.imageGetAttributes(id, (int) array[idx[i]]); - long module = attrs[LOCATION_ATTRIBUTE_MODULE]; - long parent = attrs[LOCATION_ATTRIBUTE_PARENT]; - long base = attrs[LOCATION_ATTRIBUTE_BASE]; - long ext = attrs[LOCATION_ATTRIBUTE_EXTENSION]; - - if ((module >= 0) && (module < stringsSize) - && (parent >= 0) && (parent < stringsSize) - && (base != 0) - && (ext >= 0) && (ext < stringsSize)) { - } else { - System.out.printf("Failed. Read attribute offset %d (position %d) but wrong offsets\n", - array[idx[i]], idx[i]); - System.out.printf(" offsets: module = %d parent = %d base = %d extention = %d\n", - module, parent, base, ext); - throw new RuntimeException("Read attribute offset error"); - } - } else { - System.out.printf("Failed. Could not read attribute offset %d (position %d)\n", - array[idx[i]], idx[i]); - throw new RuntimeException("Read attribute offset error"); - } - } - } finally { - wb.imageCloseImage(id); - } - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageGetDataAddressTest.java --- a/test/runtime/modules/ImageFile/ImageGetDataAddressTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test accessing the data address of a jimage. This only makes sense when the - * entire jimage is mapped into memory. - * @test ImageGetDataAddressTest - * @summary Unit test for JVM_ImageGetDataAddress() method - * @library /testlibrary /../../test/lib - * @build ImageGetDataAddressTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageGetDataAddressTest + - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageGetDataAddressTest - - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageGetDataAddressTest { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean isMMap = args[0].equals("+"); - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = wb.imageOpenImage(imageFile, bigEndian); - - // get data for valid id - long dataAddr = wb.imageGetDataAddress(id); - assertFalse((dataAddr == 0) && isMMap, "Failed. Data address is " + dataAddr + " for valid id\n"); - - // get data for invalid id == 0 - dataAddr = wb.imageGetDataAddress(0); - assertTrue(dataAddr == 0, "Failed. Data address is " + dataAddr + " for zero id\n"); - - wb.imageCloseImage(id); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageGetIndexAddressTest.java --- a/test/runtime/modules/ImageFile/ImageGetIndexAddressTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test the address of the jimage index. - * @test ImageGetIndexAddressTest - * @summary Unit test for JVM_ImageGetIndexAddress() method - * @library /testlibrary /../../test/lib - * @build ImageGetIndexAddressTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetIndexAddressTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageGetIndexAddressTest { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = wb.imageOpenImage(imageFile, bigEndian); - - // get index for valid id - long indexAddr = wb.imageGetIndexAddress(id); - assertFalse(indexAddr == 0, "Failed. Index address is zero for valid id"); - - // get index for invalid id == 0 - indexAddr = wb.imageGetIndexAddress(0); - assertTrue(indexAddr == 0, "Failed. Index address is" + indexAddr + " for zero id\n"); - - wb.imageCloseImage(id); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageGetStringBytesTest.java --- a/test/runtime/modules/ImageFile/ImageGetStringBytesTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test that the string referenced by an attribute is retrieved. - * @test ImageGetStringBytesTest - * @summary Unit test for JVM_ImageGetStringBytes() method - * @library /testlibrary /../../test/lib - * @build LocationConstants ImageGetStringBytesTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageGetStringBytesTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageGetStringBytesTest implements LocationConstants { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - long id = wb.imageOpenImage(imageFile, bigEndian); - - String className = "/java.base/java/lang/String.class"; - long[] offsetArr = wb.imageFindAttributes(id, className.getBytes()); - - // Module - assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_MODULE, "Module")); - - // Parent - assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_PARENT, "Parent")); - - // Base - assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_BASE, "Base")); - - // Extension - assertTrue(checkAttribute(id, offsetArr, LOCATION_ATTRIBUTE_EXTENSION, "Extension")); - - wb.imageCloseImage(id); - } - - private static boolean checkAttribute(long id, long[] offsetArr, int attrId, String attrName) { - long offset = offsetArr[attrId]; - return wb.imageGetStringBytes(id, (int) offset) != null; - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageOpenTest.java --- a/test/runtime/modules/ImageFile/ImageOpenTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test image opening/closing - * @test ImageOpenTest - * @summary Unit test for JVM_ImageOpen() method - * @library /testlibrary /../../test/lib - * @build ImageOpenTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ImageOpenTest - */ - -import java.io.File; -import java.nio.ByteOrder; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageOpenTest { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String nonexistentImageFile = javaHome + "/lib/modules/nonexistent.jimage"; - String bootmodulesImageFile = javaHome + File.separator + "lib" + File.separator - + "modules" + File.separator + "bootmodules.jimage"; - - if (!(new File(bootmodulesImageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN; - - // open nonexistent image - long id = wb.imageOpenImage(nonexistentImageFile, bigEndian); - assertTrue(id == 0L, "Failed. Get id " + id + "instead of 0 on opening nonexistent file\n"); - wb.imageCloseImage(id); - - // open bootmodules image - id = wb.imageOpenImage(bootmodulesImageFile, bigEndian); - assertFalse(id == 0, "Failed. Get id 0 on opening bootmodules.jimage"); - wb.imageCloseImage(id); - - // non-native endian - id = wb.imageOpenImage(bootmodulesImageFile, !bigEndian); - assertFalse(id == 0, "Failed. Get id 0 on opening bootmodules.jimage with non-native endian"); - wb.imageCloseImage(id); - - // - // open several times - // - id = wb.imageOpenImage(bootmodulesImageFile, bigEndian); - long id1 = wb.imageOpenImage(bootmodulesImageFile, bigEndian); - long id2 = wb.imageOpenImage(bootmodulesImageFile, bigEndian); - assertTrue((id == id1) && (id == id2), "Failed. Open thee times with ids " + id + " " + id1 + " " + id1); - - wb.imageCloseImage(id); - wb.imageCloseImage(id1); - wb.imageCloseImage(id2); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/ImageReadTest.java --- a/test/runtime/modules/ImageFile/ImageReadTest.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -/* - * Test reading resource content. - * @test ImageReadTest - * @summary Unit test for JVM_ImageRead() method - * @library /testlibrary /../../test/lib - * @build LocationConstants ImageReadTest - * @run main ClassFileInstaller sun.hotspot.WhiteBox - * sun.hotspot.WhiteBox$WhiteBoxPermission - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+MemoryMapImage ImageReadTest + - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-MemoryMapImage ImageReadTest - - */ - -import java.io.File; -import java.nio.ByteBuffer; -import sun.hotspot.WhiteBox; -import static jdk.test.lib.Asserts.*; - -public class ImageReadTest implements LocationConstants { - - public static final WhiteBox wb = WhiteBox.getWhiteBox(); - - public static void main(String... args) throws Exception { - String javaHome = System.getProperty("java.home"); - String imageFile = javaHome + File.separator + "lib" - + File.separator + "modules" + File.separator - + "bootmodules.jimage"; - - if (!(new File(imageFile)).exists()) { - System.out.printf("Test skipped."); - return; - } - - boolean isMMap = args[0].equals("+"); - - long id = wb.imageOpenImage(imageFile, isMMap); - - final String mm = isMMap ? "-XX:+MemoryMapImage" : "-XX:-MemoryMapImage"; - final int magic = 0xCAFEBABE; - - String className = "/java.base/java/lang/String.class"; - long[] offsetArr = wb.imageFindAttributes(id, className.getBytes()); - long offset = offsetArr[LOCATION_ATTRIBUTE_OFFSET]; - long size = offsetArr[LOCATION_ATTRIBUTE_UNCOMPRESSED]; - - // positive: read - ByteBuffer buf = ByteBuffer.allocateDirect((int) size); - assertTrue(wb.imageRead(id, offset, buf, size), "Failed. Read operation returned false, should be true"); - int m = buf.getInt(); - assertTrue(m == magic, "Failed. Read operation returned true but wrong magic = " + magic); - - // positive: mmap - if (isMMap) { - long dataAddr = wb.imageGetDataAddress(id); - assertFalse(dataAddr == 0L, "Failed. Did not obtain data address on mmapped test"); - int data = wb.imageGetIntAtAddress(dataAddr, (int) offset, true); - assertTrue(data == magic, "Failed. MMap operation returned true but wrong magic = " + data); - } - - // negative: wrong offset - boolean success = wb.imageRead(id, -100, buf, size); - assertFalse(success, "Failed. Read operation (wrong offset): returned true"); - - // negative: too big offset - long filesize = new File(imageFile).length(); - success = wb.imageRead(id, filesize + 1, buf, size); - assertFalse(success, "Failed. Read operation (offset > file size) returned true"); - - // negative: negative size - success = wb.imageRead(id, offset, buf, -100); - assertFalse(success, "Failed. Read operation (negative size) returned true"); - - wb.imageCloseImage(id); - } -} diff -r ceb9d9044fc8 -r 262b86c271b0 test/runtime/modules/ImageFile/LocationConstants.java --- a/test/runtime/modules/ImageFile/LocationConstants.java Fri Sep 04 09:47:35 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2015, 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. - */ - -public interface LocationConstants { - // keep this in sync with enum in ImageLocation C++ class in the - // hotspot's C++ header file imageFile.hpp - public static final int LOCATION_ATTRIBUTE_END = 0; // End of attribute stream marker - public static final int LOCATION_ATTRIBUTE_MODULE = 1; // String table offset of module name - public static final int LOCATION_ATTRIBUTE_PARENT = 2; // String table offset of resource path parent - public static final int LOCATION_ATTRIBUTE_BASE = 3; // String table offset of resource path base - public static final int LOCATION_ATTRIBUTE_EXTENSION = 4; // String table offset of resource path extension - public static final int LOCATION_ATTRIBUTE_OFFSET = 5; // Container byte offset of resource - public static final int LOCATION_ATTRIBUTE_COMPRESSED = 6; // In image byte size of the compressed resource - public static final int LOCATION_ATTRIBUTE_UNCOMPRESSED = 7; // In memory byte size of the uncompressed resource - public static final int LOCATION_ATTRIBUTE_COUNT = 8; // Number of attribute kinds -}