A non issue. I discussed using NIO buffers with Alan. That is the direction we will go.
> On Mar 11, 2016, at 11:36 AM, Mandy Chung <mandy.ch...@oracle.com> wrote: > > We rework the VM initialization such that lambdas can be used very early > after phase 1 initialization is done and before module system initialization. > > I’m not sure where jimage uses of lambdas for this case. In general, we > wanted to enable use of new language features early during startup and we > have this solve in jake (startup performance is a different topic). > > Mandy > >> On Mar 11, 2016, at 6:27 AM, Roger Riggs <roger.ri...@oracle.com> wrote: >> >> Thanks Jim. >> >> Beware of use of Lambdas, jimage may be used early enough in the boot cycle >> that lambdas >> are not yet fully operative. The failure is pretty obvious but can be >> trial and error to narrow it down. >> >> It would be useful to create an jira entry for the changes that are being >> delayed. >> >> Roger >> >> >> On 3/10/2016 6:22 PM, Jim Laskey (Oracle) wrote: >>> Thank you Roger. Comments inline. In general, I will hold off changes >>> until after merge so as not to destabilize. Note that ImageBufferCache and >>> Decompression are not currently used. >>> >>>> On Mar 8, 2016, at 2:07 PM, Roger Riggs <roger.ri...@oracle.com> wrote: >>>> >>>> Hi, >>>> >>>> Review comments for the jimage code in java.base, mostly cleanup but >>>> perhaps a bug or two. >>>> General: inconsistent style and not following guidelines, copyright dates >>>> may need an update. >>>> Use of assert for error checking is not going to catch or help isolate >>>> errors in production builds. >>> Noted. >>> >>>> dir: jdk/src/java.base/share/classes/jdk/internal/jimage/ >>>> >>>> >>>> BasicImageReader: >>>> - readHeader() exception message should say not a jimage or wrong version >>>> Other IOExceptions can occur if the file is corrupted or is too small, >>>> array index out of bounds, etc. >>> Replaced with specific exceptions. >>> >>>> - findLocation() should use a more explicit computation for the redirection >>>> than rehashing; this would allow the hash seed to be encapsulated. >>> As part of the review change set, I've documented the Minimal Perfect Hash >>> Method (see PerfectHashBuilder.) The algorithm requires a one time one >>> rehash when there is a collision. A new seed forces a different >>> distribution of the colliding strings. If you started with the existing >>> hashCode, you would not get a new distribution, merely a shift of all the >>> colliding elements. Random distribution is the essence of algorithm. >>> >>>> - slice() synchronizes on the ByteBuffer; does every other access? >>> Byte buffer use here is immutable, however slicing of the ByteBuffer does >>> require modifying position and limit. Wrapping or cloning the buffers >>> would be of little benefit and would take a performance hit. The >>> ByteBuffer API might have been well served with an atomic non-modifying >>> slice operation. >>> >>>> - getAllLocations() is unused and does not respect its sorted argument; >>>> Best to remove the method for now. >>> Removed. >>> >>>> - getResourceBuffer(): unused - remove >>> Removed. >>> >>>> - getResourceStream(): unused - remove >>> Removed. >>> >>>> ImageStringsReader: >>>> >>>> - Is Modified UTF-8 really needed here; using normal UTF-8 would allow >>>> re-use and better performance. Alternatively, Modified UTF-8 should be >>>> added as a supported encoding. >>> Modified UTF-8 is used to be more compact and to simplify use in native >>> code. The jimage string table has overlapping use with constant pool >>> compaction so is really an older revision of the Modified UTF-8 standard. >>> Not sure why Modifed UTF-8 is not offered as an encoding. It would have >>> made constant pool management easier. And note that relying on a particular >>> encoding is problematic. Encoding standards do change, affecting the >>> stability of the hash algorithm and may prevent the reading of older jimage >>> files. >>> >>>> - The ImageStringsReader.hashCode() should be defined so it can take >>>> advantage of 32 or 64 bit accesses; since it is used frequently. And it >>>> needs to be stable across revisions that may be accessing jimages from >>>> different JDK versions. >>>> >>> Reasonable and will consider. Not sure what you mean by stable across >>> revisions. This is not string hashCode. This is a hashCode that is >>> specific to MPHM and is deterministic. >>> >>>> - stringFromMUTF8(byte[]) - there may be some optimization to avoid >>>> expanding ascii to chars and then re-encoding in String. >>> Will touch base with the Aleksey. >>> >>>> - charsFromByteBufferLength/charsFromByteBuffer should throw an exception >>>> if no terminating null, not just when assertions are enabled >>> Will throw InternalError instead. >>> >>>> - inconsistent assert errors vs exceptions for malformed mutf8. >>>> Use of assert will not detect errors in production builds >>> Will throw InternalError instead. >>> >>>> - mutf8FromChars allocates a new working buffer (byte[8]) potentially for >>>> every UNICODE char. >>> Will hoist the buffer allocation and reuse. >>> >>>> - mutf8FromString: should take advantage of new String(bytes, offset, >>>> length, charsetName) to avoid extra allocations. >>>> (would need a Modified utf-8 charset). >>> Modified UTF-8 not available. >>> >>>> - hashCode(byte[0, seed) should be private; the hashcode algorithm should >>>> not be variable. >>>> >>> This is not String hashCode. see above. >>> >>>> ImageLocation: >>>> - Merge ImageLocation functions into ImageLocationBase and rename. >>>> ImageLocation does not have enough unique functionality to be a separate >>>> class. >>> Merged. >>> >>>> - It is a poor design to create an instance that may not be valid. >>>> It would be better to have an ImageLocation factory method that >>>> encapsulated the creation and checking >>>> >>> Noted. >>> >>>> ImageLocationBase: >>>> - Failing asserts will not cause a runtime error in production. >>>> But will degenerate into unpredictable other exceptions >>> Will throw InternalError instead. >>> >>>> ImageStream: >>>> - compress(): Too heavyweight an object to be used and discarded just for >>>> compress / decompress of small values. >>> compress()? I don’t see ImageStream used anywhere except for large >>> buffers. As a note, dynamic ByteBuffers really should be part of the JDK. >>> >>>> >>>> ImageBufferCache: >>>> - Comments on each method would make the intent clear >>> Will add comments. >>> >>>> - getBuffer: mixing for loop and explicit indexes is fragile >>>> - releaseBuffer: check buffer.capacity before threadLocal.get() for early >>>> return >>>> - Logic of i,j is flawed, i is never changed; j is/becomes 0 >>>> The first buffer is removed if there are more than max >>>> Its not clear what algorithm was intended. >>>> A buffer that is in use can be removed. >>> Rewrote using lambdas to clarify the algorithm. >>> >>>> - ImageBufferCache constructor: the isUsed flag should be set in >>>> getBuffer() >>>> when it is added to the list (not in the constructor) >>>> It keeps it consistent with when it is set for a re-used buffer. >>>> >>> Modified. >>> >>>> ImageHeader: >>>> - BADMAGIC is not used >>> Removed. >>> >>>> - readFrom could throw BufferUnderflowException - undocumented >>> get(i) can IndexOutOfBoundsException [and get() BufferUnderflowException] >>> Will add explicit check. >>> >>> >>>> ImageModuleData: >>>> - ImageModuleData seems to be unused; allModuleNames() is unreferenced >>>> >>> Removed. >>> >>>> ImageReader: >>>> - ImageReader(path): unused - remove >>> Removed. >>> >>>> - Use of assert is non-reassuring, ineffective in production builds >>> Added explicit check. >>> >>>> - In a long running application the per thread buffers will get to the >>>> point wehere they are unused and should be released. >>>> There is no support for soft or weak references to handle that case. >>>> Alternatively, if the buffers were not per thread then they would have a >>>> lesser impact. >>> The core libs team was concerned about the performance of class loading. >>> The pattern used here is the one followed by NIO. We will probably come up >>> with a shared NIO cache at some point. >>> >>>> Also, why should there be more than one buffer per thread? >>> The image cache is only used by 32 bit systems and decompression. It is >>> possible for a channel read buffer and a decompression buffer to be >>> allocated at the same time. >>> >>>> ImageReader.Resource: >>>> - unused create method >>> Removed. >>> >>>> - unused parent argument (0) in Resource constructor (dir, loc, attr) >>> Removed. >>> >>>> ImageReader.LinkNode: >>>> - constructor has unused parent arg >>>> >>>> >>> Removed >>> >>>> decompress/CompressIndexes: >>>> - readInt: wasteful allocation of a single byte array and then another >>>> small byte array; >>>> and then another heap buffer allocation in the ByteBuffer. >>> Removed all allocation. >>> >>>> - decompress is hugely wasteful of allocations of ByteBuffers of small >>>> sizes. >>>> >>> Removed all allocation. >>> >>> >>>> decompress/CompressedResourceHeader: >>>> - MAGIC does not need to be public >>>> >>>> >>>> decompress/Decompressor: >>>> - IOException "Plugin name not found" should include the missing name >>>> >>>> - StringsProvider is an unnecessary interface; could use Supplier<String> >>>> >>>> - Redundant public modifiers in interface declarations >>>> >>>> decompress/SignatureParser: >>>> - Comments describing the input and output formats needed >>>> >>>> - style around operators does not consistently include spaces; and "if("... >>>> >>>> decompress/StringSharingDecompressor: >>>> - Wasteful use of ByteBuffers and small arrays without re-use (safeAdd...) >>>> >>>> - StringSharingDecompressor constructor with unused argument - remove >>>> >>>> >>>> decompress/ZipDecompressor: >>>> - Should be more specific about the zip algorithms supported >>>> since it needs to be stable across releases >>>> >>>> - decompress(): use try-with-resources for safer inflation >>>> >>> I think decompression needs significant reworking.. >>> >>>> src/java.base/share/native/libjimage/imageDecompressor.cpp >>>> - "// If ptr is not aligned, sparc will fail." implies input argument must >>>> be aligned >>>> >>>> - General doubt about using assert; for example to check on malloc >>>> allocation failure >>>> >>>> - In production environment will exhibit as segv >>>> >>> Noted. >>> >> >