diff -r fae5b41ec06c -r b5cb9a07591a hotspot/src/share/vm/prims/jvm.cpp --- a/hotspot/src/share/vm/prims/jvm.cpp Thu Jun 25 13:23:36 2015 +0000 +++ b/hotspot/src/share/vm/prims/jvm.cpp Thu Jun 25 18:25:19 2015 +0200 @@ -24,6 +24,8 @@ #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" @@ -69,6 +71,7 @@ #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" @@ -3665,3 +3668,244 @@ 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