From alanb at openjdk.java.net Sun Nov 1 16:08:54 2020 From: alanb at openjdk.java.net (Alan Bateman) Date: Sun, 1 Nov 2020 16:08:54 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) In-Reply-To: References: Message-ID: On Thu, 29 Oct 2020 14:13:40 GMT, Maurizio Cimadamore wrote: >>> @mcimadamore, if you pull from current master, you would get the Linux x86_32 tier1 run "for free". >> >> Just did that - I also removed TestMismatch from the problem list in the latest iteration, and fixed the alignment for long/double layouts, after chatting with the team (https://bugs.openjdk.java.net/browse/JDK-8255350) > > I've just uploaded another iteration which addresses some comments from @AlanBateman. Basically, there are some operations on Channel and Socket which take ByteBuffer as arguments, and then, if such buffers are *direct*, they get the address and pass it down to some native function. This idiom is problematic because there's no way to guarantee that the buffer won't be closed (if obtained from a memory segment) after the address has been obtained. As a stop gap solution, I've introduced checks in `DirectBuffer::address` method, which is used in around 30 places in the JDK. This method will now throw if (a) the buffer has a shared scope, or (b) if the scope is confined, but already closed. With this extra check, I believe there's no way to misuse the buffer obtained from a segment. We have discussed plans to remove this limitations (which we think will be possible) - but for the time being, it's better to play the conservative card. I looked through the changes in this update. The shared memory segment support looks sound and the mechanism to close a shared memory segment is clever (albeit a bit surprising at first that it does global handshake to look for a frame in a scoped region. Also surprising that close can cause failure at both ends - it took me a while to see that this is pragmatic approach). The share method specifies NPE if thread == null but there is no thread parameter, is this a cut 'n paste error? Another one in registerCleaner where it should be NPE if the cleaner is null. I think the javadoc for the close method needs to be a bit clearer on the state of the memory segment when IllegalStateException is thrown. Will it be marked "not alive" when it fails? Does this mean there is a resource leak? I think an apiNote to explain the rational for why close is not idempotent is also needed, or maybe it should be re-visited so that close is a no-op when the memory segment is not alive. Now that MemorySegment is AutoCloseable then maybe the term "alive" should be replaced with "open" or "closed" and isAlive replaced with isOpen is isClosed. FileDescriptor can be attraction nuisance and forced reference counting everywhere that it is used. Is it needed? Could an isMapped method work instead? mapFromPath was in the second preview but I think the method name should be re-examined as it maps a file, the path just locates the file. Naming is subjectives but in this case using "map" or "mapFile" would fit beside the allocateNative methods. MappedMemorySegments. The force method specifies a write back guarantee but at the same time, the implNote in the class description suggests that the methods might be a no-op. You might want to adjust the wording to avoid any suggestion that force might be a no-op. The javadoc for copyFrom isn't changed in this update but I notice it specifies IndexOutOfBoundException when the source segment is larger than the receiver, have other exceptions been examined? I don't have any any comments on MemoryAccess except that it's not immediately clear why there are "Byte" methods that take a ByteOrder. Make sense for the multi-byte types of course. The updates the java/nio sources look okay but it would be helpful if the really long lines could be chopped down as it's just too hard to do side-by-side reviews when the lines are so long. A minor nit but the changes X-Buffer.java.template mess up the alignment of the parameters to copyMemory/copySwapMemory methods. ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From clanger at openjdk.java.net Sun Nov 1 23:29:53 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Sun, 1 Nov 2020 23:29:53 GMT Subject: Integrated: JDK-8255603: Memory/Performance regression after JDK-8210985 In-Reply-To: References: Message-ID: On Thu, 29 Oct 2020 15:11:09 GMT, Christoph Langer wrote: > It seems that there exists a memory/performance regression that was introduced with JDK-8210985: Update the default SSL session cache size to 20480. > > The idea to limit the maixmum SSL session cache size by itself is good. Unfortunately, as per the current implementation of sun.security.util.MemoryCache, it also modifies the initial size of the LinkedHashMap that is backing the cache to initialize with more than the maximum size. > > I suggest to restore the original behavior that initializes with an initialCapacity of 1 in most cases. That was true when before JDK-8210985, the property javax.net.ssl.sessionCacheSize was not set at all. > In case it was set, the initial size would have been like now, (javax.net.ssl.sessionCacheSize / 0.75f) + 1, which still seems strange. This pull request has now been integrated. Changeset: 64feeab7 Author: Christoph Langer URL: https://git.openjdk.java.net/jdk/commit/64feeab7 Stats: 3 lines in 1 file changed: 0 ins; 1 del; 2 mod 8255603: Memory/Performance regression after JDK-8210985 Reviewed-by: simonis, xuelei, aph ------------- PR: https://git.openjdk.java.net/jdk/pull/937 From mcimadamore at openjdk.java.net Mon Nov 2 11:11:56 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 2 Nov 2020 11:11:56 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) In-Reply-To: References: Message-ID: On Sun, 1 Nov 2020 16:06:32 GMT, Alan Bateman wrote: > Now that MemorySegment is AutoCloseable then maybe the term "alive" should be replaced with "open" or "closed" and isAlive replaced with isOpen is isClosed. While the reason for the method being called "isAlive" are mostly historical (the old Panama pointer API had such a method), I think I still stand behind the current naming scheme. For temporal bounds, I think "isAlive" works better than "isOpened". > MappedMemorySegments. The force method specifies a write back guarantee but at the same time, the implNote in the class description suggests that the methods might be a no-op. You might want to adjust the wording to avoid any suggestion that force might be a no-op. The comment that this operation could be no-op was borrowed from the `MappedByteBuffer` API; looking at the impl, it seems that you are right that, under no circumstances (unless the segment has length zero) this should be a no-op. How do you suggest I proceed? ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Mon Nov 2 11:29:54 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 2 Nov 2020 11:29:54 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) In-Reply-To: References: Message-ID: On Sun, 1 Nov 2020 16:06:32 GMT, Alan Bateman wrote: > The javadoc for copyFrom isn't changed in this update but I notice it specifies IndexOutOfBoundException when the source segment is larger than the receiver, have other exceptions been examined? This exception is consistent with other uses of this exception throughout this API (e.g. when writing a segment out of bounds). ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Mon Nov 2 11:59:09 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 2 Nov 2020 11:59:09 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v20] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Address comments from @AlanBateman ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/bd400615..8225bf2e Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=19 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=18-19 Stats: 121 lines in 9 files changed: 14 ins; 53 del; 54 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From serb at openjdk.java.net Mon Nov 2 12:15:02 2020 From: serb at openjdk.java.net (Sergey Bylokhov) Date: Mon, 2 Nov 2020 12:15:02 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v20] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 11:59:09 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: >> >> * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads >> * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually >> * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. >> >> A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. >> >> This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). >> >> A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. >> >> A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. >> >> Thanks >> Maurizio >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff: >> >> http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254163 >> >> >> >> ### API Changes >> >> * `MemorySegment` >> * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) >> * added a no-arg factory for a native restricted segment representing entire native heap >> * rename `withOwnerThread` to `handoff` >> * add new `share` method, to create shared segments >> * add new `registerCleaner` method, to register a segment against a cleaner >> * add more helpers to create arrays from a segment e.g. `toIntArray` >> * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) >> * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) >> * `MemoryAddress` >> * drop `segment` accessor >> * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment >> * `MemoryAccess` >> * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). >> * `MemoryHandles` >> * drop `withOffset` combinator >> * drop `withStride` combinator >> * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. >> * `Addressable` >> * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. >> * `MemoryLayouts` >> * A new layout, for machine addresses, has been added to the mix. >> >> >> >> ### Implementation changes >> >> There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. >> >> #### Shared segments >> >> The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. >> >> After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. >> >> Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). >> >> The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. >> >> As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. >> >> In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. >> >> To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). >> >> Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). >> >> `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. >> >> The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. >> >> #### Memory access var handles overhaul >> >> The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. >> >> This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. >> >> This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. >> >> #### Test changes >> >> Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. >> >> [1] - https://openjdk.java.net/jeps/393 >> [2] - https://openjdk.java.net/jeps/389 >> [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html >> [4] - https://openjdk.java.net/jeps/312 > > Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: > > Address comments from @AlanBateman test/jdk/java/foreign/TestCleaner.java line 8: > 6: * under the terms of the GNU General Public License version 2 only, as > 7: * published by the Free Software Foundation. Oracle designates this > 8: * particular file as subject to the "Classpath" exception as provided "Classpath exception" could be dropped? ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Mon Nov 2 14:18:14 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 2 Nov 2020 14:18:14 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v21] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Addess remaining feedback from @AlanBateman and @mrserb ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/8225bf2e..e2f69ec0 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=20 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=19-20 Stats: 5 lines in 2 files changed: 1 ins; 2 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From valeriep at openjdk.java.net Mon Nov 2 17:54:03 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 17:54:03 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 726: > 724: > 725: // check output buffer capacity > 726: if (getMode() != GCM_MODE && (output == null || Is the buffer size for GCM checked somewhere else? For decryption, it's probably ok to skip the check as no output is returned until doFinal(...). For encryption, there is still a chance for ShortBufferException? Javadoc states that for ShortBufferException, the call can be re-tried with a larger buffer. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 2 18:03:56 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 18:03:56 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files In-Reply-To: References: Message-ID: On Sat, 31 Oct 2020 03:28:24 GMT, Weijun Wang wrote: > > > > > The constants in PKCS11Exception are duplicated in PKCS11Constants. > > > ``` > > > 0x00000000, > > > ``` > > > > > > > > > vs > > > ``` > > > public static final long CKR_OK = 0x00000000L; > > > ``` > > > > > > > > > Is there any way to simplify it? > > > > > > One defines the value, the other defines the displayed String. I agree that the way it's currently done is a bit outdated and may be error prone. We can re-visit this after finishing other pending PKCS11 RFEs.. > > Since the value is already defined PKCS11Constants, we can use it in PKCSException and does not need to write 0x00000000 anymore. Ok, I see what you are saying now. Will change it to use the PKCS11Constants constants. ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From valeriep at openjdk.java.net Mon Nov 2 19:34:06 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 19:34:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Thu, 22 Oct 2020 20:11:55 GMT, Anthony Scarpino wrote: >> - I do not understand where the corruption comes from. The user provides a buffer that output is suppose to be placed into, what could it be corrupting? The existing tests (SameBuffer, in particular) works fine with this and the ByteBuffer calls. I spent a lot of time trying to get those same buffer tests to pass. >> - It was my expectation that checkOutputCapacity() is making sure all the inOfs ==<> outOfs are going to work. Does that not catch all cases? >> - outWithPadding" is excessive because it doubles the allocation for every operation followed by a copy to the original buffer, even if the original buffer was adequate. I'm ok with doing the extra alloc & copy in certain situations, but not everytime. Can you be more specific what things may fail that we don't already check for in the regression tests? > > I wrote a whole new tests to exercise all the buffers with and without offsets. Hopefully that covers the concern. The test found 4 bugs.. Well, existing tests may not catch/check all error cases. Especially, in the past, all calls w/ ByteBuffer inputs are converted to calls w/ byte[] inputs. Thus, testing is focused on byte[] scenarios. In addition, since for decryption, internal buffering is done, there may be no test checking if padding bytes are written to the output buffer. Please see my comment follows. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 2 19:39:07 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 19:39:07 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: <5pNHm_DfFSouqsnzLP_ADJOtn7tieyUsOjKY1OjJIVs=.ae872784-b379-4283-ac9b-67c3475d02bb@github.com> References: <5pNHm_DfFSouqsnzLP_ADJOtn7tieyUsOjKY1OjJIVs=.ae872784-b379-4283-ac9b-67c3475d02bb@github.com> Message-ID: <0MpzSHxVNhawHWB6LXwtjx4GDc8Qx3VcFv2ewH7PPXI=.43cf3a69-bc5b-4046-9220-12f371e3f876@github.com> On Wed, 7 Oct 2020 20:50:14 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 947: >> >>> 945: // create temporary output buffer if the estimated size is larger >>> 946: // than the user-provided buffer. >>> 947: if (output.length - outputOffset < estOutSize) { >> >> "outputCapacity" could be used to replace "output.length - outputOffset", and join the clause with the if-clause above. > > interesting.. That makes this and the if condition below it able to join again. Why changing outputCapacity to output.length - outputOffset? Aren't they the same thing and outputCapacity is already computed? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 2 19:59:03 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 19:59:03 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 19:31:14 GMT, Valerie Peng wrote: >> I wrote a whole new tests to exercise all the buffers with and without offsets. Hopefully that covers the concern. The test found 4 bugs.. > >> * I do not understand where the corruption comes from. The user provides a buffer that output is suppose to be placed into, what could it be corrupting? > Existing tests may not catch/check all error cases. Especially, in the past, all calls w/ ByteBuffer inputs are converted to calls w/ byte[] inputs. Thus, testing is focused on byte[] scenarios. In addition, since for decryption, internal buffering is done, there may be no test checking if padding bytes are written to the output buffer. Please see my comment follows. The corruption that I refer to is about the padding bytes which are now written into the output buffer with this change. > * It was my expectation that checkOutputCapacity() is making sure all the inOfs ==<> outOfs are going to work. Does that not catch all cases? checkOutputCapacity() as the name has, only changes that the output buffer is large enough. > * outWithPadding" is excessive because it doubles the allocation for every operation followed by a copy to the original buffer, even if the original buffer was adequate. I'm ok with doing the extra alloc & copy in certain situations, but not everytime. Can you be more specific what things may fail that we don't already check for in the regression tests? For example, 1) various input/output offset combinations, e.g. inOfs <,=,> outOfs, 2) Given a output buffer of 200-byte and outOfs == 0, assuming the returned decrypted data length is 160 bytes, the bytes from index 160 and onward should not be overwritten. GCM has no padding, so you may not notice any difference if this is what you are testing. This is generic CipherCore code and changes impact all ciphers. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 2 19:59:04 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 19:59:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 943: > 941: } > 942: } > 943: byte[] outBuffer = (internalOutput != null) ? internalOutput : output; With this line of change, the decrypted bytes are written into the output buffer including padding bytes. Is it not? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 2 20:29:04 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 20:29:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Thu, 8 Oct 2020 15:32:46 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 1253: >> >>> 1251: if (decrypting) { >>> 1252: if (buffered > 0) { >>> 1253: cipher.decrypt(buffer, 0, buffered, new byte[0], 0); >> >> This looks a bit strange? The output buffer is 0-length which would lead to ShortBufferException when the buffered bytes is enough to produce some output. > > This is right. decrypt() puts the data into GaloisCounterMode.ibuffer and never uses the output Hmm, right, I forgot that GCM cipher has that internal buffering. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 2 21:22:12 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 21:22:12 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v2] In-Reply-To: References: Message-ID: > Could someone please help review this PKCS#11 v3.0 header files update? > > Changes are straight-forward as below: > 1) Updated pkcs11.h, pkcs11f.h, pkcs11t.h to v3.0 > 2) Updated java side w/ the new constants definitions and name/error code mappings. > > For the native headers, it's a direct copy of the official v3.0 headers except that I have to remove the tab space, and trailing white spaces due to JDK code requirement. I verified the result using 'diff -w'. As for the java side, the edit is based on the diff of native headers. I also commented out some of the unused native identifiers at java side. > > I am adding the SHA-3 digests, signatures, and macs in a separate RFE and would need this one to be reviewed/integrated first. > > Thanks, > Valerie Valerie Peng has updated the pull request incrementally with one additional commit since the last revision: Updated with comments from Haimay and Weijun. Changed NSS constants to direct values for ease of debugging ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/917/files - new: https://git.openjdk.java.net/jdk/pull/917/files/d8a978a7..0b37b821 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=917&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=917&range=00-01 Stats: 163 lines in 3 files changed: 24 ins; 22 del; 117 mod Patch: https://git.openjdk.java.net/jdk/pull/917.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/917/head:pull/917 PR: https://git.openjdk.java.net/jdk/pull/917 From valeriep at openjdk.java.net Mon Nov 2 21:27:57 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 2 Nov 2020 21:27:57 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v2] In-Reply-To: References: Message-ID: <7SXfQD774usITN4E-OLfdqt7R5PKp5O56yCW9yxANos=.062e9aef-ab17-43d5-b34b-ed4fa7d272fe@github.com> On Sat, 31 Oct 2020 00:06:01 GMT, Hai-May Chao wrote: >> These three are just by themselves, so unless you feel strongly about, I prefer just leave them here which matches the ordering of pkcs11t.h, i.e. right before the CKM_VENDOR_DEFINED line. > > Just thought they could be moved like CKM_ECDSA_SHA3_224 to CKM_EDDSA (which are not matching to the ordering of pkcs11t.h), so we keep the ordering in PKCS11Constants. It's fine if you'd prefer as is. Thanks, I have slight preference for as is. ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From weijun at openjdk.java.net Mon Nov 2 21:37:54 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 2 Nov 2020 21:37:54 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v2] In-Reply-To: <8MpFlDgrQVFbJS_A6VW2YEGaL5Zy5WpiM4HMjC2kR34=.1fd69960-8d95-45b0-9be6-afa35baffc0f@github.com> References: <8MpFlDgrQVFbJS_A6VW2YEGaL5Zy5WpiM4HMjC2kR34=.1fd69960-8d95-45b0-9be6-afa35baffc0f@github.com> Message-ID: On Fri, 30 Oct 2020 21:47:51 GMT, Valerie Peng wrote: > > Just curious, can the Java files be generated during the build process? > > Hmm, maybe, by the java files, do you just mean PKCS11Constants class or more? I am not familiar with how to generate Java files during the build process, can you share some pointers? I can look into them for possible future enhancement. Well, any file that can was a rewrite of its C sibling. SunEC's finite field arithmetic code is generated in the build process. The generation tool is https://github.com/openjdk/jdk/blob/fd28aad72d3a13fbc2eb13293d40564e471414f3/make/jdk/src/classes/build/tools/intpoly/FieldGen.java#L35 and it's called by https://github.com/openjdk/jdk/blob/1cb7df63e7015da568b67c55a7a4468500ea564d/make/modules/java.base/Gensrc.gmk#L113 and the files are generated in the `$BUILD_OUTPUT/support/gensrc` directory. These files will be automatically merged with the human-written sources files in `src` of the same package at build time. ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From ascarpino at openjdk.java.net Mon Nov 2 22:09:03 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Mon, 2 Nov 2020 22:09:03 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 19:56:20 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 943: > >> 941: } >> 942: } >> 943: byte[] outBuffer = (internalOutput != null) ? internalOutput : output; > > With this line of change, the decrypted bytes are written into the output buffer including padding bytes. Is it not? If the output buffer provided is not big enough, it creates an internal one. Two things happened here, one the variable was renamed because I felt "outWithPadding" was misleading. The second was to only create this buffer when the length was smaller than the estimated length. Before this change it would already create and use this buffer whether it was needed or not. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Mon Nov 2 22:33:58 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Mon, 2 Nov 2020 22:33:58 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 19:55:26 GMT, Valerie Peng wrote: >>> * I do not understand where the corruption comes from. The user provides a buffer that output is suppose to be placed into, what could it be corrupting? >> Existing tests may not catch/check all error cases. Especially, in the past, all calls w/ ByteBuffer inputs are converted to calls w/ byte[] inputs. Thus, testing is focused on byte[] scenarios. In addition, since for decryption, internal buffering is done, there may be no test checking if padding bytes are written to the output buffer. Please see my comment follows. The corruption that I refer to is about the padding bytes which are now written into the output buffer with this change. > >> * It was my expectation that checkOutputCapacity() is making sure all the inOfs ==<> outOfs are going to work. Does that not catch all cases? > checkOutputCapacity() as the name has, only changes that the output buffer is large enough. > >> * outWithPadding" is excessive because it doubles the allocation for every operation followed by a copy to the original buffer, even if the original buffer was adequate. I'm ok with doing the extra alloc & copy in certain situations, but not everytime. Can you be more specific what things may fail that we don't already check for in the regression tests? > > For example, > 1) various input/output offset combinations, e.g. inOfs <,=,> outOfs, > 2) Given a output buffer of 200-byte and outOfs == 0, assuming the returned decrypted data length is 160 bytes, the bytes from index 160 and onward should not be overwritten. GCM has no padding, so you may not notice any difference if this is what you are testing. This is generic CipherCore code and changes impact all ciphers. checkOutputCapacity: Yes.. The method includes the offsets for the output buffer, which I believe would verify that the output area in the buffer with offsets is large enough. outWithPadding: I understand the situation and I am assuming there are tests that cover this case. Given it's a generic situation. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Mon Nov 2 22:48:03 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Mon, 2 Nov 2020 22:48:03 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 17:51:03 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 726: > >> 724: >> 725: // check output buffer capacity >> 726: if (getMode() != GCM_MODE && (output == null || > > Is the buffer size for GCM checked somewhere else? For decryption, it's probably ok to skip the check as no output is returned until doFinal(...). For encryption, there is still a chance for ShortBufferException? Javadoc states that for ShortBufferException, the call can be re-tried with a larger buffer. I know the short buffers were being checked, but I removed the mode check, the tests still pass fine, so I figured this must be a unnecessary change. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Tue Nov 3 00:17:58 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Tue, 3 Nov 2020 00:17:58 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GCTR.java line 153: > 151: while (processed > MAX_LEN) { > 152: encrypt(in, offset, MAX_LEN, out, 0); > 153: dst.get(out, 0, MAX_LEN); Shouldn't this be "put" instead of "get"? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Tue Nov 3 00:35:04 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Tue, 3 Nov 2020 00:35:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: <9hCp_4D4bkJUH9h53IoZ-umcb3k6f9GgpRrBtsdsDEY=.9da4f6c1-c7c7-4ade-a355-ec3200ee3fae@github.com> On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GHASH.java line 211: > 209: } > 210: > 211: inLen -= (inLen % AES_BLOCK_SIZE); Maybe the if-(inLen == 0) check should be moved down after this line to cover cases where inLen < AES_BLOCK_SIZE? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Tue Nov 3 01:12:05 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Tue, 3 Nov 2020 01:12:05 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Tue, 3 Nov 2020 00:15:37 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > src/java.base/share/classes/com/sun/crypto/provider/GCTR.java line 153: > >> 151: while (processed > MAX_LEN) { >> 152: encrypt(in, offset, MAX_LEN, out, 0); >> 153: dst.get(out, 0, MAX_LEN); > > Shouldn't this be "put" instead of "get"? Yeah.. I'm surprised that wasn't caught by the tests. I will look to see what case I need to make to check that. > src/java.base/share/classes/com/sun/crypto/provider/GHASH.java line 211: > >> 209: } >> 210: >> 211: inLen -= (inLen % AES_BLOCK_SIZE); > > Maybe the if-(inLen == 0) check should be moved down after this line to cover cases where inLen < AES_BLOCK_SIZE? Sure that makes sense. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Tue Nov 3 01:24:02 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Tue, 3 Nov 2020 01:24:02 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 448: > 446: > 447: // if src is empty, update the final block and wait for later > 448: // to finalize operation With the removal of this blockSizeCheck, the javadoc exception statement above at line 500 becomes obsolete? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Tue Nov 3 01:34:02 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Tue, 3 Nov 2020 01:34:02 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 514: > 512: } > 513: len -= remainder; > 514: ibuffer.write(in, len, remainder); Any chance that 'ibuffer' already contains earlier buffered bytes? If 'ibuffer' contains bytes. then these need to be processed before processing 'in' and you can't write the to-be-processed bytes into 'ibuffer' here. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From weijun at openjdk.java.net Tue Nov 3 17:03:59 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 3 Nov 2020 17:03:59 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v2] In-Reply-To: References: <8MpFlDgrQVFbJS_A6VW2YEGaL5Zy5WpiM4HMjC2kR34=.1fd69960-8d95-45b0-9be6-afa35baffc0f@github.com> Message-ID: <5i10RGtVxiSnB6gfVYouSDQpiI2OfbC8tg29ls19mEU=.017f36b0-b4f0-4524-87a2-c4915954a554@github.com> On Mon, 2 Nov 2020 21:33:31 GMT, Weijun Wang wrote: >>> >>> >>> Just curious, can the Java files be generated during the build process? >> >> Hmm, maybe, by the java files, do you just mean PKCS11Constants class or more? I am not familiar with how to generate Java files during the build process, can you share some pointers? I can look into them for possible future enhancement. > >> > Just curious, can the Java files be generated during the build process? >> >> Hmm, maybe, by the java files, do you just mean PKCS11Constants class or more? I am not familiar with how to generate Java files during the build process, can you share some pointers? I can look into them for possible future enhancement. > > Well, any file that was a rewrite of its C sibling. > > SunEC's finite field arithmetic code is generated in the build process. The generation tool is https://github.com/openjdk/jdk/blob/fd28aad72d3a13fbc2eb13293d40564e471414f3/make/jdk/src/classes/build/tools/intpoly/FieldGen.java#L35 and it's called by https://github.com/openjdk/jdk/blob/1cb7df63e7015da568b67c55a7a4468500ea564d/make/modules/java.base/Gensrc.gmk#L113 and the files are generated in the `$BUILD_OUTPUT/support/gensrc` directory. These files will be automatically merged with the human-written sources files in `src` of the same package at build time. I cannot add comments to unchanged lines in PKCS11Constants.java (there's no + sign on the line numbers), but the class-level comment (starting from line 50) can also be enhanced a little. 1. CK_SESSION_HANDLE appears twice. 2. The following appears in pkcs11t.h and I wonder if they can also be added here: typedef CK_ULONG CK_OTP_PARAM_TYPE; typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ typedef CK_ULONG CK_GENERATOR_FUNCTION; typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; typedef CK_ULONG CK_CERTIFICATE_CATEGORY; typedef CK_ULONG CK_PROFILE_ID; typedef CK_ULONG CK_PRF_DATA_TYPE; typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; typedef CK_ULONG CK_SP800_108_DKM_LENGTH_METHOD; typedef CK_ULONG CK_X3DH_KDF_TYPE; typedef CK_ULONG CK_X2RATCHET_KDF_TYPE; typedef CK_ULONG CK_XEDDSA_HASH_TYPE; I also found 2 bugs in pkcs11t.h. `CK_GCM_MESSAGE_PARAMS_PTR` and `CK_CCM_MESSAGE_PARAMS_PTR` are not defined as `CK_PTR` of their corresponding data types. Maybe you can report this to upstream? ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From ascarpino at openjdk.java.net Tue Nov 3 20:42:00 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Tue, 3 Nov 2020 20:42:00 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: <8QaZxFKfoBfDRLKbgC9z0Xl8Bm6WQ53wg8K8EBmClBg=.fea030af-5677-475c-a039-b47d3b5e3a50@github.com> On Tue, 3 Nov 2020 01:07:12 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/GCTR.java line 153: >> >>> 151: while (processed > MAX_LEN) { >>> 152: encrypt(in, offset, MAX_LEN, out, 0); >>> 153: dst.get(out, 0, MAX_LEN); >> >> Shouldn't this be "put" instead of "get"? > > Yeah.. I'm surprised that wasn't caught by the tests. I will look to see what case I need to make to check that. So there is only one calling method that never gives this method it more than 16 bytes. That is why testing never caught this. But it doesn't hurt performance leaving the ability to call larger input sizes. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Tue Nov 3 21:07:59 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Tue, 3 Nov 2020 21:07:59 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 541: > 539: throws IllegalBlockSizeException, ShortBufferException { > 540: checkDataLength(processed, Math.addExact(len, tagLenBytes)); > 541: Now that encrypt(byte[], int, int, byte[], int) may also store data into 'ibuffer', shouldn't this encryptFinal() method processes bytes in 'ibuffer' before processing 'in'? The check here would also needs to be updated with ibuffer.size()? If this is true, can this be covered in the added regression tests? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ecki at zusammenkunft.net Tue Nov 3 22:34:39 2020 From: ecki at zusammenkunft.net (Bernd) Date: Tue, 3 Nov 2020 23:34:39 +0100 Subject: JSSE Debug Log redirection Message-ID: Hello, since the backport of the new TLS 1.3 capable JSSE provider the debug logging of JSSE has changed. This is due to the usage of unified logging, which is not available on Java 8. There are some hints in the backport ticket (16 New Debug Logger): https://bugs.openjdk.java.net/browse/JDK-8248721 - in versions before the backport I could specify -Djavax.net.debug=all to turn on internal debug logging. - This was sent to stdout and it DID honor System.setOut() redirection. This especially means on an application server like JBoss the output is redirected to the (rolling) application server main logfile, but in the last two quarterly updates, this is no longer the case. This looks like a regression to me, the new internal debug loggers used by JSSE should still write to System.out (and honor redirect) However, I see that the new JUL logger (and in future the platform logger) have their benefit, so suppose I want to make changes to my existing code to accommodate this, how can I actually access and redirect those log messages? According to the backport request there is some difference between requesting a JUL logger or creating a internal one dependning on the value of the system propery. So I tried to register a handler to see if I can catch those log messages, but I have not. It works for some messages like the Debug from X509Certificate, but it does not work for the handshake stuff: (in the following console output "JUL " is from my handler and "java.net.ssl|..." is from the internal handling, it will not honor System.setOut redirects, either.) java version "1.8.0_261" Java(TM) SE Runtime Environment (build 1.8.0_261-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode) JUL FINE|1604441741129 started JUL FINE|1604441741129 ssl started JUL FINE|1604441741129 ssl started Connect to https://www.google.com ... *javax.net.ssl*|FINE|01|main|2020-11-03 23:15:41.270 CET| *SSLContextImpl.java*:425|System property jdk.tls.client.cipherSuites is set to 'null' javax.net.ssl|FINE|01|main|2020-11-03 23:15:41.275 CET|SSLContextImpl.java:425|System property jdk.tls.server.cipherSuites is set to 'null' *JUL FINE*|1604441741327 *X509Certificate*: Alg:{0}, Serial:{1}, Subject:{2}, Issuer:{3}, Key type:{4}, Length:{5}, Cert Id:{6}, Valid from:{7}, Valid until:{8} JUL FINE|1604441741328 X509Certificate: Alg:{0}, Serial:{1}, Subject:{2}, Issuer:{3}, Key type:{4}, Length:{5}, Cert Id:{6}, Valid from:{7}, Valid until:{8} ... javax.net.ssl|FINE|01|main|2020-11-03 23:15:42.358 CET|Finished.java:522|Consuming server Finished handshake message ( "Finished": { "verify data": { 0000: 46 40 BF 48 6E 83 A9 7F 6A E0 5A 4D }'} ) JUL FINE|1604441742359 TLSHandshake: {0}:{1}, {2}, {3}, {4} Using TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 -- iterates registered loggers: log javax.net.ssl null log sun.net.www.protocol.http.HttpURLConnection null log jdk.event.security null log global null log ALL JUL close JUL close ... I get the same output with -Djava.net.debug=all and -Djava.net.debug. Looks like the SSLContextImpl or Dinished.java is always using its own logger with no way to register an handler? Gruss Bernd PS: the sample code is here: /* SPDX-License-Identifier: apache-2.0 */ package net.eckenfels.test.ssl; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.Enumeration; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; import javax.net.ssl.HttpsURLConnection; import net.eckenfels.test.ssl.UrlInspect.MyHandler; public class UrlInspect { public static class MyHandler extends Handler { @Override public void publish(LogRecord record) { System.out.println("JUL " + record.getLevel() + "|" + record.getMillis() + " " + record.getMessage()); } @Override public void flush() { System.out.println("JUL flush"); System.out.flush(); } @Override public void close() throws SecurityException { System.out.println("JUL close"); } } public static void main(String[] args) throws IOException { Handler mh = new MyHandler(); LogManager.getLogManager().reset(); Logger root = LogManager.getLogManager().getLogger(""); root.setLevel(Level.ALL); root.addHandler(mh); Logger log = Logger.getLogger("javax.net.ssl"); log.addHandler(mh); // not needed root.fine("started"); log.fine("ssl started"); //FileOutputStream log = new FileOutputStream(new File("out.log")); //System.setOut(new PrintStream(log)); //sun.util.logging.PlatformLogger.getLogger("sun.net.www.protocol.http.HttpsURLConnection") .setLevel(Level.ALL); URL url = new URL((args.length < 1)?"https://developer.google.com ":args[0]); System.out.println("Connect to " + url + " ..."); HttpURLConnection.setFollowRedirects(false); HttpsURLConnection c = (HttpsURLConnection)url.openConnection(); c.connect(); // throws SSL handshake exception System.out.println("Using " + c.getCipherSuite()); System.out.println("-- iterate registered loggers"); Enumeration e = LogManager.getLogManager().getLoggerNames(); while(e.hasMoreElements()) { String n = e.nextElement(); System.out.println("log " + n + " " + Logger.getLogger(n).getLevel()); } } } -------------- next part -------------- An HTML attachment was scrubbed... URL: From valeriep at openjdk.java.net Wed Nov 4 00:37:01 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Wed, 4 Nov 2020 00:37:01 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 746: > 744: len += buffer.remaining(); > 745: } > 746: ct.mark(); This seems redundant given the ct.mark() call on line 732? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Wed Nov 4 00:49:02 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Wed, 4 Nov 2020 00:49:02 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: <3p-Ku5T-sPpa-vSIeXhyBVSxiwCUr57MlXqXABUuDsY=.904caeaa-b392-4648-8c45-9654f9e53516@github.com> On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 770: > 768: checkDataLength(0, len); > 769: > 770: if ((ibuffer.size() + ct.remaining()) - tagLenBytes > ct is set a new limit (minus the tag length) on line 741. So this check seems incorrect? How about using the 'len' value which seems to be the overall input size which should also be the expected output size? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From bradford.wetmore at oracle.com Wed Nov 4 02:08:34 2020 From: bradford.wetmore at oracle.com (Bradford Wetmore) Date: Tue, 3 Nov 2020 18:08:34 -0800 Subject: GREASE'd ALPN values - a RFC 8701 / RFC 7301 / JEP 244 discussion In-Reply-To: References: Message-ID: <97b7afb6-29d7-aee5-30b3-1e662e66017b@oracle.com> On 10/8/2020 9:20 AM, Alexander Scheel wrote: > Hi all, > > I saw that ALPN support from JEP 244 was backported to JDK8 and I've > recently had the time to take a closer look at it. For context, I'm > one of the maintainers of JSS, a NSS wrapper for Java. I've been > discussing this with another contributor, Fraser (cc'd). Hi, thanks for looking it over, and especially thanks for reporting this. I've filed: https://bugs.openjdk.java.net/browse/JDK-8254631 to track. > One of the concerns we have with the implementation (and its exposure > in the corresponding SSLEngine/SSLSocket/SSLParameters interface) is > that protocols are passed in as Strings. However, RFC 7301 says in > section 6: > >> o Identification Sequence: The precise set of octet values that >> identifies the protocol. This could be the UTF-8 encoding >> [RFC3629] of the protocol name. This "could be" is probably what the original designer of the ALPN API went with for API ease-of-use, and it made sense at the time as everything in the IANA TLS Extensions list was in the ASCII range (0x00-0x7F). But the GREASE values (0x80-0xFF) invalidated that assumption. > When applied with GREASE'd values from RFC 8701, Strings don't work > well. In particular, most of the registered values [0] are non-UTF-8, 0x0A-0x7A does work, but 0x8A-0xFA won't as you pointed out. > which can't be easily round-tripped in Java. This means that while > precise octet values are specified by IANA, they cannot be properly > specified in Java. > > In particular: > > byte[] desired = new byte[]{ (byte) 0xFA, (byte) 0xFA }; > String encoded = new String(desired, StandardCharsets.UTF_8); > byte[] wire = encoded.getBytes(StandardCharsets.UTF_8); > String round = new String(wire, StandardCharsets.UTF_8); Right. These 2 values are mapped by the decoder to 2 Object Replacement Characters ("?" - \ufffd) representing 6 bytes: 0xef, 0xbf, 0xbd, 0xef, 0xbf, 0xbd https://www.fileformat.info/info/unicode/char/fffd/index.htm > fails, as does choosing US_ASCII for the encoding: > > byte[] desired = new byte[]{ (byte) 0xFA, (byte) 0xFA }; > String encoded = new String(desired, StandardCharsets.US_ASCII); > byte[] wire = encoded.getBytes(StandardCharsets.UTF_8); > String round = new String(wire, StandardCharsets.UTF_8); Yes, US_ASCII only uses the first 7 bits, so it also maps to 2 replacement characters ("?"): 0x3f 0x3f > Note that we (at the application level) can't control the final (wire > / round-tripped) encoding to UTF_8 as this is done within the SunJSSE > implementation: Correct. > and perhaps other files I'm missing. > > This decreases interoperability with other TLS implementations. > OpenSSL [1], NSS [2], and GnuTLS [3] support setting opaque blobs as > the ALPN protocol list, meaning the caller is free to supply GREASE'd > values. Go on the other hand still uses its string [4], but that > string class supports round-tripping non-UTF8 values correctly [5]. > > Additionally, it means that GREASE'd values sent by Java applications > aren't compliant with the RFC 8701/IANA wire values. > > Is there some workaround I'm missing? Nothing is coming to mind. > I believe that setting US_ASCII internally in SunJSSE isn't sufficient > to ensure the right wire encoding gets used. I'm thinking the only > real fix is to deprecate the String methods and provide byte[] methods > for all identifiers. There is one other option that doesn't introduce a new API but does have some compatibility risk, and that is to use the ISO_8859_1/LATIN-1 charset instead of UTF-8. This would require folks who use UTF-8 to update their code, but I haven't yet found any code in the wild which actually uses anything U+0080 and above. I'm proposing a Security (or System?) property which would revert the behavior if it becomes a problem. See the attached file, which is a proposal+code example which will eventually be turned into a formal CSR barring any significant issue. I talked to our CSR lead, he felt that in this case, interoperability probably trumps compatibility for character values that likely aren't being used anyway, and behavior that was underspecified. Brad -------------- next part -------------- /* * Copyright (c) 2020, 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. */ import java.nio.charset.StandardCharsets; /* * (This text will likely form the basis of a future CSR.) * * https://bugs.openjdk.java.net/browse/JDK-8254631 * * ALPN (RFC7301) values are sent in TLS extensions using byte arrays, but the * Java ALPN APIs selected Strings for ease of use. Internally, these Java * Strings are converted to byte arrays using UTF-8 as suggested as a possible * encoding in Section 6 of RFC 7301. This encoding convention was never * specified by the RFC or Java documentation/APIs. * * It is currently not possible for ALPN characters in the range of * (U+0080-U+00FF) to be output in SunJSSE, which are instead converted to a * multi-byte representation by the UTF-8 encoder/decoder. * * The GREASE mechanism (RFC 8701) was subsequently developed to help prevent * extensibility failures in the TLS ecosystem. Unfortunately, 1/2 of the * defined GREASE values fall into the (U+0080-U+00FF) range, and thus can't be * represented by SunJSSE (client or server side). * * A new API could be defined to use byte arrays, but this would be not be * helpful for earlier Java releases (8/11/15) without a Maintenance * Release (MR). e.g. * * https://jcp.org/aboutJava/communityprocess/mrel/jsr337/index3.html * * The proposed workaround/fix is to have the Java JSSE implementation encode * Strings directly as ISO_8859_1/LATIN-1 which correctly outputs * (U+0000-U+00FF), but other UNICODE values U+8000-U+10FFFF will need to be * converted by applications to multiple consecutive bytes before sending * (e.g. UTF-8) rather than depending on SunJSSE to automatically provide * the (possibly incorrect) encoding. * * We don't anticipate this to be a significant interoperability issue, since * all known/current values in the IETF/IANA TLS ALPN extension list can be * encoded as ISO_8859_1/LATIN-1: * * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * * This change will actually enhance interoperabibility with other * implementations which use byte arrays. * * The only compatability issue is if characters larger than U+007F are used. * We don't know of any applications currently using such ALPN values, but * there could be. These values must be converted to the format required by * their peer. * * For compatibility issues, we introduce the following Java Security Property * to reverse this change: * * # * # The default Character set for converting ALPN values between byte * # arrays and Strings. Older versions of JDK used UTF-8. * # * # jdk.jsse.alpnCharacterEncoder=UTF-8 * jdk.tls.alpnCharacterEncoder=ISO_8859_1 * * which can be overridden to restore the previous conversion process. */ public class ALPNStringToBytesExample { /* * Any Unicode/Supplemental Unicode Values that need to be passed as UTF-8 * must be first converted (see below): * * 'MEETEI MAYEK LETTER HUK' * 'MEETEI MAYEK LETTER UN' * 'MEETEI MAYEK LETTER I' * * 'DESERET CAPITAL LETTER LONG I' * 'DESERET CAPITAL LETTER LONG E' */ private static final String HUKUNI = "\uabcd\uabce\uabcf"; private static final String IE = new String(new int[]{0x10400, 0x10401}, 0, 2); // ALPN String array that will eventually be passed to SSLEngine/SSLSocket. private static final String[] ALPN_STRINGS = new String[]{ // From the IETF/IANA TLS ALPN extension list. // ASCII/ISO_8859_1/LATIN-1 Strings "http/1.1", // 0x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 "h2", // 0x68 0x32 "imap", // 0x69 0x6d 0x61 0x70 "sunrpc", // 0x73 0x75 0x6e 0x72 0x70 0x63 // etc. // GREASE (RFC 8701) toISO_8859_1((byte) 0x0A, (byte) 0x0A), toISO_8859_1((byte) 0x1A, (byte) 0x1A), toISO_8859_1((byte) 0x2A, (byte) 0x2A), toISO_8859_1((byte) 0x3A, (byte) 0x3A), toISO_8859_1((byte) 0x4A, (byte) 0x4A), toISO_8859_1((byte) 0x5A, (byte) 0x5A), toISO_8859_1((byte) 0x6A, (byte) 0x6A), toISO_8859_1((byte) 0x7A, (byte) 0x7A), toISO_8859_1((byte) 0x8A, (byte) 0x8A), toISO_8859_1((byte) 0x9A, (byte) 0x9A), toISO_8859_1((byte) 0xAA, (byte) 0xAA), toISO_8859_1((byte) 0xBA, (byte) 0xBA), toISO_8859_1((byte) 0xCA, (byte) 0xCA), toISO_8859_1((byte) 0xDA, (byte) 0xDA), toISO_8859_1((byte) 0xEA, (byte) 0xEA), toISO_8859_1((byte) 0xFA, (byte) 0xFA), // Additional Regular and Supplemental Unicode Points (above) toISO_8859_1(HUKUNI.getBytes(StandardCharsets.UTF_8)), toISO_8859_1(IE.getBytes(StandardCharsets.UTF_8)) }; public static void main(String[] args) throws Exception { /* * Create SSLEngine and set ALPN parameters. * * SSLContext sslContext = SSLContext.getDefault(); * SSLEngine sslEngine = sslContext.createSSLEngine("peer", 80); * SSLParameters sslParameters = sslEngine.getSSLParameters(); * sslParameters.setApplicationProtocols(ALPN_VALUES); * sslEngine.setSSLParameters(sslParameters); * sslEngine.beginHandshake(); sslEngine.wrap()/unwrap(); * // etc. */ /* * Local SunJSSE will now encode the String array as ISO_8859_1 * byte array as expected by RFC 8701. */ byte[][] outgoingBytes = new byte[ALPN_STRINGS.length][0]; for (int i = 0; i < ALPN_STRINGS.length; i++) { outgoingBytes[i] = ALPN_STRINGS[i].getBytes(StandardCharsets.ISO_8859_1); } /* * Peer SunJSSE receives byte array and parses back into ISO_8859_1 * String array. */ String[] incomingStrings = new String[outgoingBytes.length]; for (int i = 0; i < incomingStrings.length; i++) { incomingStrings[i] = new String(outgoingBytes[i], StandardCharsets.ISO_8859_1); } // Check the ASCII/LATIN chars. for (int i = 0; i < incomingStrings.length - 2; i++) { checkStrings(i, incomingStrings[i], ALPN_STRINGS[i]); } // Last 2 Strings need to be decoded back as UTF-8. checkStrings(incomingStrings.length - 2, toUTF_8String(incomingStrings[incomingStrings.length - 2]), HUKUNI); checkStrings(incomingStrings.length - 1, toUTF_8String(incomingStrings[incomingStrings.length - 1]), IE); } // Shorten method calls above. private static String toISO_8859_1(byte... bytes) { return new String(bytes, StandardCharsets.ISO_8859_1); } // Shorten method calls above. private static String toUTF_8String(String incomingString) { return new String(incomingString.getBytes( StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); } private static void checkStrings(int i, String incoming, String alpn) { System.out.println(i + ": \"" + incoming + "\" = \"" + alpn + "\""); if (!incoming.equals(alpn)) { System.out.println("ISO_8859_1 didn't convert cleanly"); } } } From valeriep at openjdk.java.net Wed Nov 4 04:24:57 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Wed, 4 Nov 2020 04:24:57 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v2] In-Reply-To: <5i10RGtVxiSnB6gfVYouSDQpiI2OfbC8tg29ls19mEU=.017f36b0-b4f0-4524-87a2-c4915954a554@github.com> References: <8MpFlDgrQVFbJS_A6VW2YEGaL5Zy5WpiM4HMjC2kR34=.1fd69960-8d95-45b0-9be6-afa35baffc0f@github.com> <5i10RGtVxiSnB6gfVYouSDQpiI2OfbC8tg29ls19mEU=.017f36b0-b4f0-4524-87a2-c4915954a554@github.com> Message-ID: On Tue, 3 Nov 2020 16:58:45 GMT, Weijun Wang wrote: > > > https://github.com/openjdk/jdk/blob/0b37b821a10325d9083c23130e4b8921812ed9c5/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/wrapper/PKCS11Constants.java#L54 > > I cannot add comments to unchanged lines in PKCS11Constants.java (there's no + sign on the line numbers), but the class-level comment (starting from line 56) can also be enhanced a little. Sure, I will update them as well. > 1. CK_SESSION_HANDLE appears twice. > > 2. The following appears in pkcs11t.h and I wonder if they can also be added here: > > > ``` > typedef CK_ULONG CK_OTP_PARAM_TYPE; > typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* backward compatibility */ > typedef CK_ULONG CK_GENERATOR_FUNCTION; > typedef CK_ULONG CK_JAVA_MIDP_SECURITY_DOMAIN; > typedef CK_ULONG CK_CERTIFICATE_CATEGORY; > typedef CK_ULONG CK_PROFILE_ID; > typedef CK_ULONG CK_PRF_DATA_TYPE; > typedef CK_MECHANISM_TYPE CK_SP800_108_PRF_TYPE; > typedef CK_ULONG CK_SP800_108_DKM_LENGTH_METHOD; > typedef CK_ULONG CK_X3DH_KDF_TYPE; > typedef CK_ULONG CK_X2RATCHET_KDF_TYPE; > typedef CK_ULONG CK_XEDDSA_HASH_TYPE; > ``` > > I also found 2 bugs in pkcs11t.h. `CK_GCM_MESSAGE_PARAMS_PTR` and `CK_CCM_MESSAGE_PARAMS_PTR` are not defined as `CK_PTR` of their corresponding data types. Maybe you can report this to upstream? Right, these two looks wrongly defined. I will send a comment about this to the Oasic PKCS11 TC. Thanks~ ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From alanb at openjdk.java.net Wed Nov 4 07:47:55 2020 From: alanb at openjdk.java.net (Alan Bateman) Date: Wed, 4 Nov 2020 07:47:55 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) In-Reply-To: References: Message-ID: <-u4eSM47o_e_KlfTRYBNGyLNhjqAeG-84u_uEd3ppH0=.c49b4269-1001-49d1-96fd-ecacbf2417e9@github.com> On Mon, 2 Nov 2020 11:26:51 GMT, Maurizio Cimadamore wrote: >> I looked through the changes in this update. >> >> The shared memory segment support looks sound and the mechanism to close a shared memory segment is clever (albeit a bit surprising at first that it does global handshake to look for a frame in a scoped region. Also surprising that close can cause failure at both ends - it took me a while to see that this is pragmatic approach). >> >> The share method specifies NPE if thread == null but there is no thread parameter, is this a cut 'n paste error? Another one in registerCleaner where it should be NPE if the cleaner is null. >> >> I think the javadoc for the close method needs to be a bit clearer on the state of the memory segment when IllegalStateException is thrown. Will it be marked "not alive" when it fails? Does this mean there is a resource leak? I think an apiNote to explain the rational for why close is not idempotent is also needed, or maybe it should be re-visited so that close is a no-op when the memory segment is not alive. >> >> Now that MemorySegment is AutoCloseable then maybe the term "alive" should be replaced with "open" or "closed" and isAlive replaced with isOpen is isClosed. >> >> FileDescriptor can be attraction nuisance and forced reference counting everywhere that it is used. Is it needed? Could an isMapped method work instead? >> >> mapFromPath was in the second preview but I think the method name should be re-examined as it maps a file, the path just locates the file. Naming is subjectives but in this case using "map" or "mapFile" would fit beside the allocateNative methods. >> >> MappedMemorySegments. The force method specifies a write back guarantee but at the same time, the implNote in the class description suggests that the methods might be a no-op. You might want to adjust the wording to avoid any suggestion that force might be a no-op. >> >> The javadoc for copyFrom isn't changed in this update but I notice it specifies IndexOutOfBoundException when the source segment is larger than the receiver, have other exceptions been examined? >> >> I don't have any any comments on MemoryAccess except that it's not immediately clear why there are "Byte" methods that take a ByteOrder. Make sense for the multi-byte types of course. >> >> The updates the java/nio sources look okay but it would be helpful if the really long lines could be chopped down as it's just too hard to do side-by-side reviews when the lines are so long. A minor nit but the changes X-Buffer.java.template mess up the alignment of the parameters to copyMemory/copySwapMemory methods. > >> The javadoc for copyFrom isn't changed in this update but I notice it specifies IndexOutOfBoundException when the source segment is larger than the receiver, have other exceptions been examined? > > This exception is consistent with other uses of this exception throughout this API (e.g. when writing a segment out of bounds). I assume the CSR needs to be updated so that it's in sync with the API changes in the latest round. ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From valeriep at openjdk.java.net Wed Nov 4 20:52:11 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Wed, 4 Nov 2020 20:52:11 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v3] In-Reply-To: References: Message-ID: <0JD-hJ_4ysUcZBKN66I3LzlkAyXRRSOnHQIvjK8jVTI=.c4aea5d6-2263-437d-a090-0b3d3c9a3d55@github.com> > Could someone please help review this PKCS#11 v3.0 header files update? > > Changes are straight-forward as below: > 1) Updated pkcs11.h, pkcs11f.h, pkcs11t.h to v3.0 > 2) Updated java side w/ the new constants definitions and name/error code mappings. > > For the native headers, it's a direct copy of the official v3.0 headers except that I have to remove the tab space, and trailing white spaces due to JDK code requirement. I verified the result using 'diff -w'. As for the java side, the edit is based on the diff of native headers. I also commented out some of the unused native identifiers at java side. > > I am adding the SHA-3 digests, signatures, and macs in a separate RFE and would need this one to be reviewed/integrated first. > > Thanks, > Valerie Valerie Peng has updated the pull request incrementally with one additional commit since the last revision: Updated the javadoc comments of PKCS11Constants class with additional typedef info Updated the legal file to new PKCS11 version ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/917/files - new: https://git.openjdk.java.net/jdk/pull/917/files/0b37b821..03f1b67a Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=917&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=917&range=01-02 Stats: 25 lines in 2 files changed: 15 ins; 5 del; 5 mod Patch: https://git.openjdk.java.net/jdk/pull/917.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/917/head:pull/917 PR: https://git.openjdk.java.net/jdk/pull/917 From weijun at openjdk.java.net Wed Nov 4 21:08:58 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Wed, 4 Nov 2020 21:08:58 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v3] In-Reply-To: <0JD-hJ_4ysUcZBKN66I3LzlkAyXRRSOnHQIvjK8jVTI=.c4aea5d6-2263-437d-a090-0b3d3c9a3d55@github.com> References: <0JD-hJ_4ysUcZBKN66I3LzlkAyXRRSOnHQIvjK8jVTI=.c4aea5d6-2263-437d-a090-0b3d3c9a3d55@github.com> Message-ID: On Wed, 4 Nov 2020 20:52:11 GMT, Valerie Peng wrote: >> Could someone please help review this PKCS#11 v3.0 header files update? >> >> Changes are straight-forward as below: >> 1) Updated pkcs11.h, pkcs11f.h, pkcs11t.h to v3.0 >> 2) Updated java side w/ the new constants definitions and name/error code mappings. >> >> For the native headers, it's a direct copy of the official v3.0 headers except that I have to remove the tab space, and trailing white spaces due to JDK code requirement. I verified the result using 'diff -w'. As for the java side, the edit is based on the diff of native headers. I also commented out some of the unused native identifiers at java side. >> >> I am adding the SHA-3 digests, signatures, and macs in a separate RFE and would need this one to be reviewed/integrated first. >> >> Thanks, >> Valerie > > Valerie Peng has updated the pull request incrementally with one additional commit since the last revision: > > Updated the javadoc comments of PKCS11Constants class with additional > typedef info > Updated the legal file to new PKCS11 version Marked as reviewed by weijun (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From hchao at openjdk.java.net Thu Nov 5 00:24:01 2020 From: hchao at openjdk.java.net (Hai-May Chao) Date: Thu, 5 Nov 2020 00:24:01 GMT Subject: RFR: 8244154: Update SunPKCS11 provider with PKCS11 v3.0 header files [v3] In-Reply-To: References: <0JD-hJ_4ysUcZBKN66I3LzlkAyXRRSOnHQIvjK8jVTI=.c4aea5d6-2263-437d-a090-0b3d3c9a3d55@github.com> Message-ID: On Wed, 4 Nov 2020 21:06:35 GMT, Weijun Wang wrote: >> Valerie Peng has updated the pull request incrementally with one additional commit since the last revision: >> >> Updated the javadoc comments of PKCS11Constants class with additional >> typedef info >> Updated the legal file to new PKCS11 version > > Marked as reviewed by weijun (Reviewer). Incr webrev looks good. ------------- PR: https://git.openjdk.java.net/jdk/pull/917 From ascarpino at openjdk.java.net Thu Nov 5 16:54:01 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Thu, 5 Nov 2020 16:54:01 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Tue, 3 Nov 2020 01:31:37 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 514: > >> 512: } >> 513: len -= remainder; >> 514: ibuffer.write(in, len, remainder); > > Any chance that 'ibuffer' already contains earlier buffered bytes? If 'ibuffer' contains bytes. then these need to be processed before processing 'in' and you can't write the to-be-processed bytes into 'ibuffer' here. I does not. CipherCore only sends block sized data, and the ByteBuffer code uses this method during final operations. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From mcimadamore at openjdk.java.net Thu Nov 5 17:14:16 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 5 Nov 2020 17:14:16 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v22] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 29 commits: - Fix post-merge issues caused by 8219014 - Merge branch 'master' into 8254162 - Addess remaining feedback from @AlanBateman and @mrserb - Address comments from @AlanBateman - Merge branch 'master' into 8254162 - Fix issues with derived buffers and IO operations - More 32-bit fixes for TestLayouts - * Add final to MappedByteBuffer::SCOPED_MEMORY_ACCESS field * Tweak TestLayouts to make it 32-bit friendly after recent MemoryLayouts tweaks - Remove TestMismatch from 32-bit problem list - Merge branch 'master' into 8254162 - ... and 19 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...02f9e251 ------------- Changes: https://git.openjdk.java.net/jdk/pull/548/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=21 Stats: 7608 lines in 80 files changed: 4859 ins; 1545 del; 1204 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From ascarpino at openjdk.java.net Thu Nov 5 17:41:00 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Thu, 5 Nov 2020 17:41:00 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: <82wdHJU17pINQFWn-IBYSl-7CY3_mxAphMnbcmXf61M=.c8b3016d-090c-40ba-928f-ace4c61080b7@github.com> On Tue, 3 Nov 2020 21:03:02 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 541: > >> 539: throws IllegalBlockSizeException, ShortBufferException { >> 540: checkDataLength(processed, Math.addExact(len, tagLenBytes)); >> 541: > > Now that encrypt(byte[], int, int, byte[], int) may also store data into 'ibuffer', shouldn't this encryptFinal() method processes bytes in 'ibuffer' before processing 'in'? The check here would also needs to be updated with ibuffer.size()? If this is true, can this be covered in the added regression tests? This is not an optimized path for bytebuffers and will never have any data in ibuffer. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Thu Nov 5 19:02:10 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Thu, 5 Nov 2020 19:02:10 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: <3p-Ku5T-sPpa-vSIeXhyBVSxiwCUr57MlXqXABUuDsY=.904caeaa-b392-4648-8c45-9654f9e53516@github.com> References: <3p-Ku5T-sPpa-vSIeXhyBVSxiwCUr57MlXqXABUuDsY=.904caeaa-b392-4648-8c45-9654f9e53516@github.com> Message-ID: On Wed, 4 Nov 2020 00:46:13 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 770: > >> 768: checkDataLength(0, len); >> 769: >> 770: if ((ibuffer.size() + ct.remaining()) - tagLenBytes > > > ct is set a new limit (minus the tag length) on line 741. So this check seems incorrect? > How about using the 'len' value which seems to be the overall input size which should also be the expected output size? Yeah, I'd agree > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 746: > >> 744: len += buffer.remaining(); >> 745: } >> 746: ct.mark(); > > This seems redundant given the ct.mark() call on line 732? Does seem redundant.. I'll remove and see how testing goes ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ecki at zusammenkunft.net Thu Nov 5 19:11:31 2020 From: ecki at zusammenkunft.net (Bernd Eckenfels) Date: Thu, 5 Nov 2020 19:11:31 +0000 Subject: RFR: JDK-8255395 Implement Enhanced Pseudo-Random Number Generators (CSR) In-Reply-To: References: Message-ID: Hello, Not sure if it is needed to implement a new RandumGenerator interface instead of extending SecureRandom, but the extensions and the discovery mechanism looks good. One thing I am wondering about is if reseed() and reseed(Param) should be part of the new RandomGenerator interface as well. BTW a lot of the random number Discovery and configuration could have been avoided when the actual implementation just would have been stronger and less blocking. The focus should be on the two old factory methods to make them return top quality, it?s hard enough to make everyone use them for the correct use case. Gruss Bernd -- http://bernd.eckenfels.net ________________________________ Von: core-libs-dev im Auftrag von Jim Laskey Gesendet: Thursday, November 5, 2020 2:02:24 PM An: core-libs-dev Betreff: RFR: JDK-8255395 Implement Enhanced Pseudo-Random Number Generators (CSR) Please review the CSR for JEP-356 Enhanced Pseudo-Random Number Generators. Thank you. -- Jim CSR: https://bugs.openjdk.java.net/browse/JDK-8255395 JBS: https://bugs.openjdk.java.net/browse/JDK-8248862 JEP: http://openjdk.java.net/jeps/356 -------------- next part -------------- An HTML attachment was scrubbed... URL: From ascarpino at openjdk.java.net Thu Nov 5 20:07:01 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Thu, 5 Nov 2020 20:07:01 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Mon, 12 Oct 2020 20:57:50 GMT, Valerie Peng wrote: >> I didn't see a way to override this because CipherSpi is a public class, any methods I added would become a new API. >> Also bufferCrypt is private, so I had to copy it. CipherSpi does not know which mode is being used, but AESCipher does. Maybe I'm missing something, I'd rather it not be a copy, but I couldn't see a better way. If you have a specific idea, please give me details. > > How about overriding > protected int engineDoFinal(ByteBuffer input, ByteBuffer output) throws ... { > if (core.getMode() == CipherCore.GCM_MODE && !input.hasArray()) { > // call your own optimized byte buffer code path > } else { > super.engineDoFinal(input, output); > } > } > > Would this work? If yes, then no need to duplicate the whole bufferCrypt() method. Good call.. I wouldn't have thought about super. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From mcimadamore at openjdk.java.net Thu Nov 5 21:26:16 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 5 Nov 2020 21:26:16 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: - Merge branch '8254162' into 8254231_linker - Fix post-merge issues caused by 8219014 - Merge branch 'master' into 8254162 - Addess remaining feedback from @AlanBateman and @mrserb - Address comments from @AlanBateman - Fix typo in upcall helper for aarch64 - Merge branch '8254162' into 8254231_linker - Merge branch 'master' into 8254162 - Fix issues with derived buffers and IO operations - More 32-bit fixes for TestLayouts - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f ------------- Changes: https://git.openjdk.java.net/jdk/pull/634/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=14 Stats: 75292 lines in 271 files changed: 72365 ins; 1626 del; 1301 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From valeriep at openjdk.java.net Thu Nov 5 22:59:04 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Thu, 5 Nov 2020 22:59:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 23 Oct 2020 16:38:01 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: > > - style > - style & comments > - full update > - remove old > - update > - outputsize test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java line 443: > 441: > 442: datamap.put("AES/GCM/NoPadding", List.of( > 443: new Data("AES", Just curious, is the data self-generated or got from some spec/external sources? test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java line 34: > 32: * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=false CheckSessionContext > 33: * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext > 34: * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=false -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext I am not sure how is this test related to the change? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Fri Nov 6 03:26:04 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Fri, 6 Nov 2020 03:26:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Thu, 5 Nov 2020 22:54:45 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with six additional commits since the last revision: >> >> - style >> - style & comments >> - full update >> - remove old >> - update >> - outputsize > > test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java line 443: > >> 441: >> 442: datamap.put("AES/GCM/NoPadding", List.of( >> 443: new Data("AES", > > Just curious, is the data self-generated or got from some spec/external sources? The last one, in this diff, is generated by me. The previous ones are KAT. > test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java line 34: > >> 32: * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=false CheckSessionContext >> 33: * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext >> 34: * @run main/othervm -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=false -Djdk.tls.client.enableSessionTicketExtension=true CheckSessionContext > > I am not sure how is this test related to the change? I think I changed this when I was running the tests so I could see my GCM results better using TLS. It is not directly testing the change ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From fguallini at openjdk.java.net Fri Nov 6 12:38:05 2020 From: fguallini at openjdk.java.net (Fernando Guallini) Date: Fri, 6 Nov 2020 12:38:05 GMT Subject: RFR: 8255546: Missing coverage for javax.smartcardio.CardPermission and ResponseAPDU Message-ID: This patch is to add code coverage to the following methods - javax.smartcardio.CardPermission::**implies** (1) - javax.smartcardio.ResponseAPDU::**toString** (2) Tests are added following the expected implementation given in the methods specifications (1) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java#L214-L229 (2) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/ResponseAPDU.java#L141-L149 ------------- Commit messages: - refactor smartcardio test in order to be more comprehensive - add code coverage for CardPermission.implies and ResponseAPDU.toString Changes: https://git.openjdk.java.net/jdk/pull/1092/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1092&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8255546 Stats: 122 lines in 2 files changed: 82 ins; 12 del; 28 mod Patch: https://git.openjdk.java.net/jdk/pull/1092.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1092/head:pull/1092 PR: https://git.openjdk.java.net/jdk/pull/1092 From coleenp at openjdk.java.net Fri Nov 6 22:41:05 2020 From: coleenp at openjdk.java.net (Coleen Phillimore) Date: Fri, 6 Nov 2020 22:41:05 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Thu, 5 Nov 2020 21:26:16 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: > > - Merge branch '8254162' into 8254231_linker > - Fix post-merge issues caused by 8219014 > - Merge branch 'master' into 8254162 > - Addess remaining feedback from @AlanBateman and @mrserb > - Address comments from @AlanBateman > - Fix typo in upcall helper for aarch64 > - Merge branch '8254162' into 8254231_linker > - Merge branch 'master' into 8254162 > - Fix issues with derived buffers and IO operations > - More 32-bit fixes for TestLayouts > - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 58: > 56: #if 0 > 57: fprintf(stderr, "upcall_init()\n"); > 58: #endif There shouldn't be #if 0 debugging code in the final version. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 55: > 53: > 54: // FIXME: This should be initialized explicitly instead of lazily/racily > 55: static void upcall_init() { The FIXME is right this should be initialized as a well known class and referred to here as SystemDictionary::ProgrammableUpcallHandler_klass(). This really doesn't belong here. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 81: > 79: #endif > 80: > 81: Method* method = k->lookup_method(mname_sym, mdesc_sym); This "method" appears unused. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 76: > 74: #endif > 75: > 76: Klass* k = SystemDictionary::resolve_or_null(cname_sym, THREAD); pass CATCH if you expect this to never throw an ClassNotFoundException. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 68: > 66: Symbol* cname_sym = SymbolTable::new_symbol(cname, (int)strlen(cname)); > 67: Symbol* mname_sym = SymbolTable::new_symbol(mname, (int)strlen(mname)); > 68: Symbol* mdesc_sym = SymbolTable::new_symbol(mdesc, (int)strlen(mdesc)); You don't need the strlen() argument. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 121: > 119: upcall_info.upcall_method.name, upcall_info.upcall_method.sig, > 120: &args, thread); > 121: } This code shouldn't be in the cpu directory. This should be in SharedRuntime or in jni.cpp. It should have a JNI_ENTRY and not transition directly. I don't know what AttachCurrentThreadAsDaemon does. src/hotspot/share/prims/universalNativeInvoker.hpp line 28: > 26: > 27: #include "classfile/javaClasses.hpp" > 28: #include "classfile/vmSymbols.hpp" This file doesn't seem to need all of these #include files. src/hotspot/share/prims/universalNativeInvoker.hpp line 37: > 35: #ifdef ZERO > 36: # include "entry_zero.hpp" > 37: #endif needed? Or does the header file that declares ProgrammableStub need this? src/hotspot/share/prims/universalUpcallHandler.cpp line 2: > 1: /* > 2: * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. New files should only have 2020 even though this might have been checked into a branch before. There are a bunch of new files that have old copyrights I noticed. src/hotspot/share/prims/universalUpcallHandler.cpp line 52: > 50: guarantee(status == JNI_OK && !env->ExceptionOccurred(), > 51: "register jdk.internal.foreign.abi.ProgrammableUpcallHandler natives"); > 52: JNI_END Why isn't that other function here? src/hotspot/share/prims/universalUpcallHandler.hpp line 30: > 28: #include "classfile/vmSymbols.hpp" > 29: #include "include/jvm.h" > 30: #include "runtime/frame.inline.hpp" None of these header files seem to be needed here. src/hotspot/share/runtime/init.cpp line 40: > 38: #include "prims/methodHandles.hpp" > 39: #include "prims/universalNativeInvoker.hpp" > 40: #include "runtime/globals.hpp" This looks like the only change so why do you need the #includes? src/hotspot/share/runtime/thread.hpp line 1574: > 1572: return byte_offset_of(JavaThread, _anchor); > 1573: } > 1574: blank line, revert this if this is the only change here to avoid conflicts. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From coleenp at openjdk.java.net Fri Nov 6 22:41:06 2020 From: coleenp at openjdk.java.net (Coleen Phillimore) Date: Fri, 6 Nov 2020 22:41:06 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 21:47:42 GMT, Coleen Phillimore wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 81: > >> 79: #endif >> 80: >> 81: Method* method = k->lookup_method(mname_sym, mdesc_sym); > > This "method" appears unused. This should be moved into javaClasses or common code. resolve_or_null only resolves the class, it doesn't also call the initializer for the class so you shouldn't be able to call a static method on the class. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From valeriep at openjdk.java.net Fri Nov 6 23:06:00 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 6 Nov 2020 23:06:00 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 22:06:15 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java line 943: >> >>> 941: } >>> 942: } >>> 943: byte[] outBuffer = (internalOutput != null) ? internalOutput : output; >> >> With this line of change, the decrypted bytes are written into the output buffer including padding bytes. Is it not? > > If the output buffer provided is not big enough, it creates an internal one. Two things happened here, one the variable was renamed because I felt "outWithPadding" was misleading. The second was to only create this buffer when the length was smaller than the estimated length. Before this change it would already create and use this buffer whether it was needed or not. I understand the renaming and etc. The difference here is that if output buffer is large enough, then the padding bytes are written into the output buffer even though the returned output length does not count them. Before this change, a separate output buffer is always used. Do you think it's ok to output padding bytes into user-supplied buffer? This is my main concern about this line. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 6 23:12:06 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 6 Nov 2020 23:12:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: <2gfKNtUb1TOpRCFwFY9ZxZy9GxyypI1KCk0OX3WGtHo=.08e701c7-3e2d-4734-8dba-9db36700f79f@github.com> On Thu, 5 Nov 2020 16:51:34 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 514: >> >>> 512: } >>> 513: len -= remainder; >>> 514: ibuffer.write(in, len, remainder); >> >> Any chance that 'ibuffer' already contains earlier buffered bytes? If 'ibuffer' contains bytes. then these need to be processed before processing 'in' and you can't write the to-be-processed bytes into 'ibuffer' here. > > I does not. CipherCore only sends block sized data, and the ByteBuffer code uses this method during final operations. Hmm, ok, this is getting obscure and the correctness is depending on the calling pattern. Can we add a check on line 514 to ensure that there is no bytes in ibuffer? >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 541: >> >>> 539: throws IllegalBlockSizeException, ShortBufferException { >>> 540: checkDataLength(processed, Math.addExact(len, tagLenBytes)); >>> 541: >> >> Now that encrypt(byte[], int, int, byte[], int) may also store data into 'ibuffer', shouldn't this encryptFinal() method processes bytes in 'ibuffer' before processing 'in'? The check here would also needs to be updated with ibuffer.size()? If this is true, can this be covered in the added regression tests? > > This is not an optimized path for bytebuffers and will never have any data in ibuffer. Hmm, ok, can we add a check on ibuffer size here just to be sure? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From alanb at openjdk.java.net Sun Nov 8 08:12:56 2020 From: alanb at openjdk.java.net (Alan Bateman) Date: Sun, 8 Nov 2020 08:12:56 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) In-Reply-To: <-u4eSM47o_e_KlfTRYBNGyLNhjqAeG-84u_uEd3ppH0=.c49b4269-1001-49d1-96fd-ecacbf2417e9@github.com> References: <-u4eSM47o_e_KlfTRYBNGyLNhjqAeG-84u_uEd3ppH0=.c49b4269-1001-49d1-96fd-ecacbf2417e9@github.com> Message-ID: On Wed, 4 Nov 2020 07:45:09 GMT, Alan Bateman wrote: >>> The javadoc for copyFrom isn't changed in this update but I notice it specifies IndexOutOfBoundException when the source segment is larger than the receiver, have other exceptions been examined? >> >> This exception is consistent with other uses of this exception throughout this API (e.g. when writing a segment out of bounds). > > I assume the CSR needs to be updated so that it's in sync with the API changes in the latest round. I see the xxxByteAtIndex methods that took a ByteOrder have been removed from MemoryAccess. Should the xxxByte and xxxByteAtOffset that take a ByteOrder be removed too? ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From alanb at openjdk.java.net Sun Nov 8 16:31:58 2020 From: alanb at openjdk.java.net (Alan Bateman) Date: Sun, 8 Nov 2020 16:31:58 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v22] In-Reply-To: References: Message-ID: On Thu, 5 Nov 2020 17:14:16 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: >> >> * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads >> * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually >> * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. >> >> A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. >> >> This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). >> >> A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. >> >> A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. >> >> Thanks >> Maurizio >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff: >> >> http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254163 >> >> >> >> ### API Changes >> >> * `MemorySegment` >> * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) >> * added a no-arg factory for a native restricted segment representing entire native heap >> * rename `withOwnerThread` to `handoff` >> * add new `share` method, to create shared segments >> * add new `registerCleaner` method, to register a segment against a cleaner >> * add more helpers to create arrays from a segment e.g. `toIntArray` >> * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) >> * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) >> * `MemoryAddress` >> * drop `segment` accessor >> * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment >> * `MemoryAccess` >> * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). >> * `MemoryHandles` >> * drop `withOffset` combinator >> * drop `withStride` combinator >> * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. >> * `Addressable` >> * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. >> * `MemoryLayouts` >> * A new layout, for machine addresses, has been added to the mix. >> >> >> >> ### Implementation changes >> >> There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. >> >> #### Shared segments >> >> The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. >> >> After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. >> >> Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). >> >> The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. >> >> As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. >> >> In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. >> >> To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). >> >> Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). >> >> `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. >> >> The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. >> >> #### Memory access var handles overhaul >> >> The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. >> >> This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. >> >> This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. >> >> #### Test changes >> >> Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. >> >> [1] - https://openjdk.java.net/jeps/393 >> [2] - https://openjdk.java.net/jeps/389 >> [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html >> [4] - https://openjdk.java.net/jeps/312 > > Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 29 commits: > > - Fix post-merge issues caused by 8219014 > - Merge branch 'master' into 8254162 > - Addess remaining feedback from @AlanBateman and @mrserb > - Address comments from @AlanBateman > - Merge branch 'master' into 8254162 > - Fix issues with derived buffers and IO operations > - More 32-bit fixes for TestLayouts > - * Add final to MappedByteBuffer::SCOPED_MEMORY_ACCESS field > * Tweak TestLayouts to make it 32-bit friendly after recent MemoryLayouts tweaks > - Remove TestMismatch from 32-bit problem list > - Merge branch 'master' into 8254162 > - ... and 19 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...02f9e251 Marked as reviewed by alanb (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From dholmes at openjdk.java.net Mon Nov 9 03:26:01 2020 From: dholmes at openjdk.java.net (David Holmes) Date: Mon, 9 Nov 2020 03:26:01 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: <8bF0fXpoTGxGwg_Ea__S4LApLPhAJ9ejrOP4P_IvaiM=.14114594-11fa-415f-9008-d3be3dfaf0c3@github.com> On Thu, 5 Nov 2020 21:26:16 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: > > - Merge branch '8254162' into 8254231_linker > - Fix post-merge issues caused by 8219014 > - Merge branch 'master' into 8254162 > - Addess remaining feedback from @AlanBateman and @mrserb > - Address comments from @AlanBateman > - Fix typo in upcall helper for aarch64 > - Merge branch '8254162' into 8254231_linker > - Merge branch 'master' into 8254162 > - Fix issues with derived buffers and IO operations > - More 32-bit fixes for TestLayouts > - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 60: > 58: #endif > 59: > 60: TRAPS = Thread::current(); Don't use TRAPS this way - it exists for use in signatures. Just declare: `Thread* THREAD = Thread::current();` ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From dholmes at openjdk.java.net Mon Nov 9 04:13:07 2020 From: dholmes at openjdk.java.net (David Holmes) Date: Mon, 9 Nov 2020 04:13:07 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Thu, 5 Nov 2020 21:26:16 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: > > - Merge branch '8254162' into 8254231_linker > - Fix post-merge issues caused by 8219014 > - Merge branch 'master' into 8254162 > - Addess remaining feedback from @AlanBateman and @mrserb > - Address comments from @AlanBateman > - Fix typo in upcall helper for aarch64 > - Merge branch '8254162' into 8254231_linker > - Merge branch 'master' into 8254162 > - Fix issues with derived buffers and IO operations > - More 32-bit fixes for TestLayouts > - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f A high-level scan through - mostly VM files. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 99: > 97: if (thread == NULL) { > 98: JavaVM_ *vm = (JavaVM *)(&main_vm); > 99: vm -> functions -> AttachCurrentThreadAsDaemon(vm, &p_env, NULL); Style nit: don't put spaces around `->` operator. What is the context for this being called? It looks highly suspicious to just attach the current thread to the VM this way. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 105: > 103: assert(thread->is_Java_thread(), "really?"); > 104: > 105: ThreadInVMfromNative __tiv((JavaThread *)thread); Please use `thread->as_Java_thread()` instead of the cast. src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 111: > 109: } > 110: > 111: ResourceMark rm; Pass `thread` to the RM constructor. src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp line 3521: > 3519: __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); > 3520: > 3521: if (os::is_MP()) { The assumption these days is that we are always MP and we don't litter the code with `os::is_MP()` checks any more. src/hotspot/cpu/x86/universalUpcallHandler_x86.cpp line 53: > 51: Symbol* sig; > 52: } upcall_method; // jdk.internal.foreign.abi.UniversalUpcallHandler::invoke > 53: } upcall_info; Why is this being duplicated in platform specific code when it appears to be common/shared? src/hotspot/cpu/x86/universalUpcallHandler_x86.cpp line 56: > 54: > 55: // FIXME: This should be initialized explicitly instead of lazily/racily > 56: static void upcall_init() { Obviously see all comments on the Aarch64 files. This appears it should be common/shared code. src/hotspot/share/prims/scopedMemoryAccess.cpp line 86: > 84: void do_thread(Thread* thread) { > 85: > 86: JavaThread* jt = (JavaThread*)thread; Please use `thread->as_Java_thread()` instead of the cast. src/hotspot/share/prims/universalNativeInvoker.cpp line 40: > 38: assert(thread->thread_state() == _thread_in_native, "thread state is: %d", thread->thread_state()); > 39: } > 40: assert(thread->thread_state() == _thread_in_vm, "thread state is: %d", thread->thread_state()); Is there some reason you don't trust the thread-state transition code and are asserting it updates the state correctly all the time? :) There are already a number of assertions of this kind within the ThreadToNativeFromVM code. src/java.base/share/classes/jdk/internal/invoke/NativeEntryPoint.java line 63: > 61: } > 62: > 63: public static NativeEntryPoint make(long addr, String name, ABIDescriptorProxy abi, VMStorageProxy[] argMoves, VMStorageProxy[] returnMoves, Where is name validation performed, to ensure the named native method is in fact legal and not trying to provide backdoor access to native code that should be encapsulated and protected? src/java.base/windows/native/libjava/jni_util_md.c line 51: > 49: > 50: // first come, first served > 51: if(EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) { Style check: space after `if` ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From dholmes at openjdk.java.net Mon Nov 9 04:13:10 2020 From: dholmes at openjdk.java.net (David Holmes) Date: Mon, 9 Nov 2020 04:13:10 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v14] In-Reply-To: References: Message-ID: <037JOlF9tavFXVI6H6AnLiI3GSpcJLiAOANXz_KTWUg=.16b28fcd-302a-42b2-b493-cd2e4e59b9b2@github.com> On Fri, 30 Oct 2020 12:16:02 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: > > Fix typo in upcall helper for aarch64 src/java.base/share/classes/java/lang/System.java line 2086: > 2084: break; > 2085: case "allow": > 2086: allowSecurityManager = MAYBE; Why is this removed? I don't see the connection. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From dholmes at openjdk.java.net Mon Nov 9 04:13:09 2020 From: dholmes at openjdk.java.net (David Holmes) Date: Mon, 9 Nov 2020 04:13:09 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 21:42:41 GMT, Coleen Phillimore wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 55: > >> 53: >> 54: // FIXME: This should be initialized explicitly instead of lazily/racily >> 55: static void upcall_init() { > > The FIXME is right this should be initialized as a well known class and referred to here as SystemDictionary::ProgrammableUpcallHandler_klass(). This really doesn't belong here. I agree with Coleen. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From ngasson at openjdk.java.net Mon Nov 9 06:10:03 2020 From: ngasson at openjdk.java.net (Nick Gasson) Date: Mon, 9 Nov 2020 06:10:03 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: <4bUSiuyN2A59lbK4owjFzfRXLm4G49lJo4ObxopBTrs=.bc8c90c7-f831-4814-b5e4-c1f1fcc4e98f@github.com> On Thu, 5 Nov 2020 21:26:16 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: > > - Merge branch '8254162' into 8254231_linker > - Fix post-merge issues caused by 8219014 > - Merge branch 'master' into 8254162 > - Addess remaining feedback from @AlanBateman and @mrserb > - Address comments from @AlanBateman > - Fix typo in upcall helper for aarch64 > - Merge branch '8254162' into 8254231_linker > - Merge branch 'master' into 8254162 > - Fix issues with derived buffers and IO operations > - More 32-bit fixes for TestLayouts > - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f src/hotspot/share/opto/output.cpp line 1697: > 1695: current_offset = cb->insts_size(); > 1696: > 1697: assert(!is_mcall || (call_returns[block->_pre_order] == (uint) current_offset), "ret_addr_offset() did not match size of emitted code"); This assertion is too strong: on AArch64 we generate additional instructions after the BLR (call) instruction for certain types of call. For example 0x0000ffff790f00dc: adr x9, 0x0000ffff790f00f4 0x0000ffff790f00e0: mov x8, #0x5714 // #22292 0x0000ffff790f00e4: movk x8, #0x8d3d, lsl #16 0x0000ffff790f00e8: movk x8, #0xffff, lsl #32 0x0000ffff790f00ec: stp xzr, x9, [sp, #-16]! 0x0000ffff790f00f0: blr x8 0x0000ffff790f00f4: add sp, sp, #0x10 <== ret_addr_offset() is here 0x0000ffff790f00f8: Address 0x0000ffff790f00f8 is out of bounds. <== current_offset is here I think the `==` should be `<=`. (Although this still fails sometimes on AArch64, but I believe it exposes a real bug. I've opened JDK-8256025 and will fix this shortly.) ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From sibabrata.sahoo at oracle.com Mon Nov 9 06:22:51 2020 From: sibabrata.sahoo at oracle.com (sibabrata.sahoo at oracle.com) Date: Mon, 9 Nov 2020 11:52:51 +0530 Subject: RFR: 8255546: Missing coverage for javax.smartcardio.CardPermission and ResponseAPDU In-Reply-To: References: Message-ID: <261EE1B9-7C1F-40D2-880D-E947BC4B52D1@oracle.com> So you have converted the Test to use JUnit other than adding few new Test cases. It looks fine to me. Thanks, Siba > On 06-Nov-2020, at 6:08 PM, Fernando Guallini wrote: > > This patch is to add code coverage to the following methods > - javax.smartcardio.CardPermission::**implies** (1) > - javax.smartcardio.ResponseAPDU::**toString** (2) > > Tests are added following the expected implementation given in the methods specifications > > (1) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java#L214-L229 > > (2) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/ResponseAPDU.java#L141-L149 > > ------------- > > Commit messages: > - refactor smartcardio test in order to be more comprehensive > - add code coverage for CardPermission.implies and ResponseAPDU.toString > > Changes: https://git.openjdk.java.net/jdk/pull/1092/files > Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1092&range=00 > Issue: https://bugs.openjdk.java.net/browse/JDK-8255546 > Stats: 122 lines in 2 files changed: 82 ins; 12 del; 28 mod > Patch: https://git.openjdk.java.net/jdk/pull/1092.diff > Fetch: git fetch https://git.openjdk.java.net/jdk pull/1092/head:pull/1092 > > PR: https://git.openjdk.java.net/jdk/pull/1092 From fguallini at openjdk.java.net Mon Nov 9 10:28:58 2020 From: fguallini at openjdk.java.net (Fernando Guallini) Date: Mon, 9 Nov 2020 10:28:58 GMT Subject: RFR: 8255546: Missing coverage for javax.smartcardio.CardPermission and ResponseAPDU In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 12:04:20 GMT, Fernando Guallini wrote: > This patch is to add code coverage to the following methods > - javax.smartcardio.CardPermission::**implies** (1) > - javax.smartcardio.ResponseAPDU::**toString** (2) > > Tests are added following the expected implementation given in the methods specifications > > (1) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java#L214-L229 > > (2) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/ResponseAPDU.java#L141-L149 > _Mailing list message from [sibabrata.sahoo at oracle.com](mailto:sibabrata.sahoo at oracle.com) on [security-dev](mailto:security-dev at openjdk.java.net):_ > > So you have converted the Test to use JUnit other than adding few new Test cases. > > It looks fine to me. > > Thanks, > Siba Hi Siba, Tests were converted to Testng and coverage for CardPermission::implies and ResponseAPDU::toString was added. Thank you for reviewing ------------- PR: https://git.openjdk.java.net/jdk/pull/1092 From jvernee at openjdk.java.net Mon Nov 9 11:12:05 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 11:12:05 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: <4bUSiuyN2A59lbK4owjFzfRXLm4G49lJo4ObxopBTrs=.bc8c90c7-f831-4814-b5e4-c1f1fcc4e98f@github.com> References: <4bUSiuyN2A59lbK4owjFzfRXLm4G49lJo4ObxopBTrs=.bc8c90c7-f831-4814-b5e4-c1f1fcc4e98f@github.com> Message-ID: <3Rq38lsrqgc6urjbkdsLYLCMljA519ITzLs6cLnOEfk=.24bc9068-30f4-4a8d-91d9-20bcd61696c1@github.com> On Mon, 9 Nov 2020 06:07:32 GMT, Nick Gasson wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > src/hotspot/share/opto/output.cpp line 1697: > >> 1695: current_offset = cb->insts_size(); >> 1696: >> 1697: assert(!is_mcall || (call_returns[block->_pre_order] == (uint) current_offset), "ret_addr_offset() did not match size of emitted code"); > > This assertion is too strong: on AArch64 we generate additional instructions after the BLR (call) instruction for certain types of call. For example > > > 0x0000ffff790f00dc: adr x9, 0x0000ffff790f00f4 > 0x0000ffff790f00e0: mov x8, #0x5714 // #22292 > 0x0000ffff790f00e4: movk x8, #0x8d3d, lsl #16 > 0x0000ffff790f00e8: movk x8, #0xffff, lsl #32 > 0x0000ffff790f00ec: stp xzr, x9, [sp, #-16]! > 0x0000ffff790f00f0: blr x8 > 0x0000ffff790f00f4: add sp, sp, #0x10 <== ret_addr_offset() is here > 0x0000ffff790f00f8: Address 0x0000ffff790f00f8 is out of bounds. <== current_offset is here > > I think the `==` should be `<=`. (Although this still fails sometimes on AArch64, but I believe it exposes a real bug. I've opened JDK-8256025 and will fix this shortly.) Ok, that seems fine to me. IIRC the problem this was trying to catch is a ret_addr_offset that is too large, which might cause a later call's oop map to be overridden. So, using `<=` should still work. At least if the code between ret_addr_offset and current_offset is guaranteed not to contain any calls or other safepoints. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Mon Nov 9 11:57:07 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 11:57:07 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 03:29:05 GMT, David Holmes wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 99: > >> 97: if (thread == NULL) { >> 98: JavaVM_ *vm = (JavaVM *)(&main_vm); >> 99: vm -> functions -> AttachCurrentThreadAsDaemon(vm, &p_env, NULL); > > Style nit: don't put spaces around `->` operator. > > What is the context for this being called? It looks highly suspicious to just attach the current thread to the VM this way. The context is a thread that is spawned by native code doing an upcall. We need to attach the thread to the VM first in that case. Normally this would be handled by the calling code, but in our case the calling code doesn't know it's calling into Java. > src/java.base/share/classes/jdk/internal/invoke/NativeEntryPoint.java line 63: > >> 61: } >> 62: >> 63: public static NativeEntryPoint make(long addr, String name, ABIDescriptorProxy abi, VMStorageProxy[] argMoves, VMStorageProxy[] returnMoves, > > Where is name validation performed, to ensure the named native method is in fact legal and not trying to provide backdoor access to native code that should be encapsulated and protected? The name is just used as debugging information (in e.g. CallNativeNode::dump_spec), we are not looking it up. The address that is passed there is the actual function target. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Mon Nov 9 12:15:01 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 12:15:01 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 03:31:15 GMT, David Holmes wrote: >> src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 55: >> >>> 53: >>> 54: // FIXME: This should be initialized explicitly instead of lazily/racily >>> 55: static void upcall_init() { >> >> The FIXME is right this should be initialized as a well known class and referred to here as SystemDictionary::ProgrammableUpcallHandler_klass(). This really doesn't belong here. > > I agree with Coleen. I'll give this another try, but I think last time I tried this resolution of the class failed when trying to build the JDK, seemingly since it exists in an incubator module, which is not always added to the module graph. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Mon Nov 9 12:28:13 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 9 Nov 2020 12:28:13 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v23] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Remove endianness-aware byte getter/setter in MemoryAccess Remove index-based version of byte getter/setter in MemoryAccess ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/02f9e251..6940f0ac Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=22 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=21-22 Stats: 110 lines in 3 files changed: 0 ins; 98 del; 12 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Mon Nov 9 12:28:16 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 9 Nov 2020 12:28:16 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v22] In-Reply-To: References: Message-ID: On Sun, 8 Nov 2020 16:28:41 GMT, Alan Bateman wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 29 commits: >> >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - * Add final to MappedByteBuffer::SCOPED_MEMORY_ACCESS field >> * Tweak TestLayouts to make it 32-bit friendly after recent MemoryLayouts tweaks >> - Remove TestMismatch from 32-bit problem list >> - Merge branch 'master' into 8254162 >> - ... and 19 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...02f9e251 > > Marked as reviewed by alanb (Reviewer). > I see the xxxByteAtIndex methods that took a ByteOrder have been removed from MemoryAccess. Should the xxxByte and xxxByteAtOffset that take a ByteOrder be removed too? I've addresses this in the latest iteration. Since I was there I also removed `getByteAtIndex` and `getByteAtIndex`, since their behavior is identical to that of `getByteAtOffset` and `setByteAtOffset`, respectively (in other words, the indexed variants are not really helpful until carrier size > 1 byte). ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Mon Nov 9 13:22:14 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 9 Nov 2020 13:22:14 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v24] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Improve debugging output of TestHandhsake ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/6940f0ac..f5d339a7 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=23 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=22-23 Stats: 37 lines in 1 file changed: 11 ins; 1 del; 25 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From david.holmes at oracle.com Mon Nov 9 13:51:03 2020 From: david.holmes at oracle.com (David Holmes) Date: Mon, 9 Nov 2020 23:51:03 +1000 Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: <8c4cbff8-32b5-c90b-20da-dccfa49e970c@oracle.com> Hi Jorn, On 9/11/2020 9:57 pm, Jorn Vernee wrote: > On Mon, 9 Nov 2020 03:29:05 GMT, David Holmes wrote: > >> src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 99: >> >>> 97: if (thread == NULL) { >>> 98: JavaVM_ *vm = (JavaVM *)(&main_vm); >>> 99: vm -> functions -> AttachCurrentThreadAsDaemon(vm, &p_env, NULL); >> >> Style nit: don't put spaces around `->` operator. >> >> What is the context for this being called? It looks highly suspicious to just attach the current thread to the VM this way. > > The context is a thread that is spawned by native code doing an upcall. We need to attach the thread to the VM first in that case. Normally this would be handled by the calling code, but in our case the calling code doesn't know it's calling into Java. Apologies that I don't have enough knowledge of this feature to understand the context. Shouldn't you then detach it again afterwards? Otherwise when will it detach? If you don't detach you will get a memory leak. >> src/java.base/share/classes/jdk/internal/invoke/NativeEntryPoint.java line 63: >> >>> 61: } >>> 62: >>> 63: public static NativeEntryPoint make(long addr, String name, ABIDescriptorProxy abi, VMStorageProxy[] argMoves, VMStorageProxy[] returnMoves, >> >> Where is name validation performed, to ensure the named native method is in fact legal and not trying to provide backdoor access to native code that should be encapsulated and protected? > > The name is just used as debugging information (in e.g. CallNativeNode::dump_spec), we are not looking it up. The address that is passed there is the actual function target. Okay. Thanks, David ----- > ------------- > > PR: https://git.openjdk.java.net/jdk/pull/634 > From mcimadamore at openjdk.java.net Mon Nov 9 15:26:13 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 9 Nov 2020 15:26:13 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v25] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Further improve output of TestHandshake ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/f5d339a7..27677a13 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=24 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=23-24 Stats: 8 lines in 1 file changed: 4 ins; 2 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Mon Nov 9 16:07:13 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 9 Nov 2020 16:07:13 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v26] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Add more output in TestHandhsake.java ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/27677a13..a22b6b5b Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=25 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=24-25 Stats: 4 lines in 1 file changed: 4 ins; 0 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From jvernee at openjdk.java.net Mon Nov 9 16:34:00 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 16:34:00 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: <_Nl5ypHkLlY3aqitzjfT_Rot6lDm6TX3VS3KbTE_gBg=.4a0f5742-bad8-4ceb-805d-2e7e0c51ebf4@github.com> On Mon, 9 Nov 2020 12:11:56 GMT, Jorn Vernee wrote: >> I agree with Coleen. > > I'll give this another try, but I think last time I tried this resolution of the class failed when trying to build the JDK, seemingly since it exists in an incubator module, which is not always added to the module graph. Ok, I can confirm that moving this to be a well-known class will result in a `java/lang/NoClassDefFoundError: jdk/internal/foreign/abi/ProgrammableUpcallHandler` error while trying to build the JDK. I think this is because the particular class is in an incubator module, which is not always present. I think we'll have to stick with the lazy resolution instead. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Mon Nov 9 16:34:01 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 16:34:01 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 22:02:31 GMT, Coleen Phillimore wrote: >> src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 81: >> >>> 79: #endif >>> 80: >>> 81: Method* method = k->lookup_method(mname_sym, mdesc_sym); >> >> This "method" appears unused. > > This should be moved into javaClasses or common code. resolve_or_null only resolves the class, it doesn't also call the initializer for the class so you shouldn't be able to call a static method on the class. I'll move this to common code and add a call to `Klass::initialize` ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Mon Nov 9 16:34:05 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 16:34:05 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 22:07:39 GMT, Coleen Phillimore wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 68: > >> 66: Symbol* cname_sym = SymbolTable::new_symbol(cname, (int)strlen(cname)); >> 67: Symbol* mname_sym = SymbolTable::new_symbol(mname, (int)strlen(mname)); >> 68: Symbol* mdesc_sym = SymbolTable::new_symbol(mdesc, (int)strlen(mdesc)); > > You don't need the strlen() argument. Ok, I see it has an overload that does that in the header file (and I only looked at the .cpp file. :( ) > src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 121: > >> 119: upcall_info.upcall_method.name, upcall_info.upcall_method.sig, >> 120: &args, thread); >> 121: } > > This code shouldn't be in the cpu directory. This should be in SharedRuntime or in jni.cpp. It should have a JNI_ENTRY and not transition directly. I don't know what AttachCurrentThreadAsDaemon does. Roger that. We need the thread state transition though in case we get a random native thread calling us. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Mon Nov 9 16:37:07 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 16:37:07 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 03:52:27 GMT, David Holmes wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > src/hotspot/share/prims/universalNativeInvoker.cpp line 40: > >> 38: assert(thread->thread_state() == _thread_in_native, "thread state is: %d", thread->thread_state()); >> 39: } >> 40: assert(thread->thread_state() == _thread_in_vm, "thread state is: %d", thread->thread_state()); > > Is there some reason you don't trust the thread-state transition code and are asserting it updates the state correctly all the time? :) There are already a number of assertions of this kind within the ThreadToNativeFromVM code. Pre-existing code (to me at least). I agree it seems unnecessary, I'll remove the asserts. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Mon Nov 9 16:37:09 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Mon, 9 Nov 2020 16:37:09 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v14] In-Reply-To: <037JOlF9tavFXVI6H6AnLiI3GSpcJLiAOANXz_KTWUg=.16b28fcd-302a-42b2-b493-cd2e4e59b9b2@github.com> References: <037JOlF9tavFXVI6H6AnLiI3GSpcJLiAOANXz_KTWUg=.16b28fcd-302a-42b2-b493-cd2e4e59b9b2@github.com> Message-ID: On Mon, 9 Nov 2020 03:56:38 GMT, David Holmes wrote: >> Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix typo in upcall helper for aarch64 > > src/java.base/share/classes/java/lang/System.java line 2086: > >> 2084: break; >> 2085: case "allow": >> 2086: allowSecurityManager = MAYBE; > > Why is this removed? I don't see the connection. Seems to be a problem from a merge gone wrong. Not related as you say. Will remove ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jorn.vernee at oracle.com Mon Nov 9 15:07:48 2020 From: jorn.vernee at oracle.com (Jorn Vernee) Date: Mon, 9 Nov 2020 16:07:48 +0100 Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: <8c4cbff8-32b5-c90b-20da-dccfa49e970c@oracle.com> References: <8c4cbff8-32b5-c90b-20da-dccfa49e970c@oracle.com> Message-ID: <56e42c7c-4abf-3948-cb63-1f102acedd85@oracle.com> Hi David, On 09/11/2020 14:51, David Holmes wrote: > Hi Jorn, > > On 9/11/2020 9:57 pm, Jorn Vernee wrote: >> On Mon, 9 Nov 2020 03:29:05 GMT, David Holmes >> wrote: >> >>> src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 99: >>> >>>> 97:?? if (thread == NULL) { >>>> 98:???? JavaVM_ *vm = (JavaVM *)(&main_vm); >>>> 99:???? vm -> functions -> AttachCurrentThreadAsDaemon(vm, &p_env, >>>> NULL); >>> >>> Style nit: don't put spaces around `->` operator. >>> >>> What is the context for this being called? It looks highly >>> suspicious to just attach the current thread to the VM this way. >> >> The context is a thread that is spawned by native code doing an >> upcall. We need to attach the thread to the VM first in that case. >> Normally this would be handled by the calling code, but in our case >> the calling code doesn't know it's calling into Java. > > Apologies that I don't have enough knowledge of this feature to > understand the context. Shouldn't you then detach it again afterwards? > Otherwise when will it detach? If you don't detach you will get a > memory leak. I went back to look at the original thread that added this code [1]. At that point the decision was made to go with the memory leak to avoid additional complexity in assembly stub generation and performance loss from having to repeatedly attach and detach threads. At least the complexity argument is no longer valid. As for the performance argument. This implementation of upcalls is not expected to perform stellar, so I think calling detach again in case we did an attach is the right call. (Though we'll have to solve the same problem again down the line for the optimized version). Thanks for catching, Jorn [1] : https://mail.openjdk.java.net/pipermail/panama-dev/2019-June/005761.html >>> src/java.base/share/classes/jdk/internal/invoke/NativeEntryPoint.java >>> line 63: >>> >>>> 61:???? } >>>> 62: >>>> 63:???? public static NativeEntryPoint make(long addr, String name, >>>> ABIDescriptorProxy abi, VMStorageProxy[] argMoves, VMStorageProxy[] >>>> returnMoves, >>> >>> Where is name validation performed, to ensure the named native >>> method is in fact legal and not trying to provide backdoor access to >>> native code that should be encapsulated and protected? >> >> The name is just used as debugging information (in e.g. >> CallNativeNode::dump_spec), we are not looking it up. The address >> that is passed there is the actual function target. > > Okay. > > Thanks, > David > ----- > >> ------------- >> >> PR: https://git.openjdk.java.net/jdk/pull/634 >> From mcimadamore at openjdk.java.net Mon Nov 9 18:25:27 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 9 Nov 2020 18:25:27 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v16] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with two additional commits since the last revision: - Merge pull request #6 from JornVernee/MoveUpcallInfo Address review comments - - Use lazy constant for upcall_info - Reduce copied code between platforms - Clean up includes - Split thread attach from upcall_helper ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/b38afb3f..e9606edb Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=15 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=14-15 Stats: 463 lines in 8 files changed: 100 ins; 296 del; 67 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From dholmes at openjdk.java.net Tue Nov 10 01:51:02 2020 From: dholmes at openjdk.java.net (David Holmes) Date: Tue, 10 Nov 2020 01:51:02 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v16] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 18:25:27 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request incrementally with two additional commits since the last revision: > > - Merge pull request #6 from JornVernee/MoveUpcallInfo > > Address review comments > - - Use lazy constant for upcall_info > - Reduce copied code between platforms > - Clean up includes > - Split thread attach from upcall_helper src/hotspot/cpu/aarch64/universalNativeInvoker_aarch64.cpp line 29: > 27: #include "prims/universalNativeInvoker.hpp" > 28: #include "memory/resourceArea.hpp" > 29: #include "code/codeBlob.hpp" Nit: includes should be in alphabetical order src/hotspot/cpu/x86/universalNativeInvoker_x86.cpp line 28: > 26: #include "prims/universalNativeInvoker.hpp" > 27: #include "memory/resourceArea.hpp" > 28: #include "code/codeBlob.hpp" Nit: includes should be in alphabetical order src/hotspot/share/prims/universalUpcallHandler.cpp line 54: > 52: if (thread == nullptr) { > 53: JavaVM_ *vm = (JavaVM *)(&main_vm); > 54: vm->functions->AttachCurrentThread(vm, (void**) &p_env, nullptr); The return value should be checked in case of errors. Making this non-daemon now is probably somewhat safer. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From david.holmes at oracle.com Tue Nov 10 02:13:24 2020 From: david.holmes at oracle.com (David Holmes) Date: Tue, 10 Nov 2020 12:13:24 +1000 Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: <_Nl5ypHkLlY3aqitzjfT_Rot6lDm6TX3VS3KbTE_gBg=.4a0f5742-bad8-4ceb-805d-2e7e0c51ebf4@github.com> References: <_Nl5ypHkLlY3aqitzjfT_Rot6lDm6TX3VS3KbTE_gBg=.4a0f5742-bad8-4ceb-805d-2e7e0c51ebf4@github.com> Message-ID: On 10/11/2020 2:34 am, Jorn Vernee wrote: > On Mon, 9 Nov 2020 12:11:56 GMT, Jorn Vernee wrote: > >>> I agree with Coleen. >> >> I'll give this another try, but I think last time I tried this resolution of the class failed when trying to build the JDK, seemingly since it exists in an incubator module, which is not always added to the module graph. > > Ok, I can confirm that moving this to be a well-known class will result in a `java/lang/NoClassDefFoundError: jdk/internal/foreign/abi/ProgrammableUpcallHandler` error while trying to build the JDK. I think this is because the particular class is in an incubator module, which is not always present. Right ... well-known classes appear to be limited to being in java.base module. > I think we'll have to stick with the lazy resolution instead. I think this could still be done non-racily during VM startup, after module system initialization i.e. between: call_initPhase2() ... call_initPhase3() in Threads::create_vm. And it could still use the mechanisms in systemDictionary to define a global accessor I think, even if not initialized with the other "well known" classes. I don't have a good mental picture of how all the pieces of this connect in terms of Java APIs and VM entry points so these structuring suggestions may, or may not make sense. Potentially this could be a future cleanup anyway. Thanks, David ----- > ------------- > > PR: https://git.openjdk.java.net/jdk/pull/634 > From alanb at openjdk.java.net Tue Nov 10 11:03:55 2020 From: alanb at openjdk.java.net (Alan Bateman) Date: Tue, 10 Nov 2020 11:03:55 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v26] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 16:07:13 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: >> >> * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads >> * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually >> * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. >> >> A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. >> >> This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). >> >> A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. >> >> A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. >> >> Thanks >> Maurizio >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff: >> >> http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254163 >> >> >> >> ### API Changes >> >> * `MemorySegment` >> * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) >> * added a no-arg factory for a native restricted segment representing entire native heap >> * rename `withOwnerThread` to `handoff` >> * add new `share` method, to create shared segments >> * add new `registerCleaner` method, to register a segment against a cleaner >> * add more helpers to create arrays from a segment e.g. `toIntArray` >> * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) >> * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) >> * `MemoryAddress` >> * drop `segment` accessor >> * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment >> * `MemoryAccess` >> * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). >> * `MemoryHandles` >> * drop `withOffset` combinator >> * drop `withStride` combinator >> * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. >> * `Addressable` >> * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. >> * `MemoryLayouts` >> * A new layout, for machine addresses, has been added to the mix. >> >> >> >> ### Implementation changes >> >> There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. >> >> #### Shared segments >> >> The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. >> >> After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. >> >> Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). >> >> The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. >> >> As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. >> >> In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. >> >> To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). >> >> Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). >> >> `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. >> >> The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. >> >> #### Memory access var handles overhaul >> >> The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. >> >> This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. >> >> This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. >> >> #### Test changes >> >> Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. >> >> [1] - https://openjdk.java.net/jeps/393 >> [2] - https://openjdk.java.net/jeps/389 >> [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html >> [4] - https://openjdk.java.net/jeps/312 > > Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: > > Add more output in TestHandhsake.java Marked as reviewed by alanb (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Tue Nov 10 12:10:26 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Tue, 10 Nov 2020 12:10:26 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v17] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Address more CSR feedback ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/e9606edb..9960b3d7 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=16 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=15-16 Stats: 50 lines in 6 files changed: 0 ins; 30 del; 20 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Tue Nov 10 14:16:22 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Tue, 10 Nov 2020 14:16:22 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: - Merge pull request #7 from JornVernee/Additional_Review_Comments Additional review comments - Revert System.java changes - Set copyright year for added files to 2020 - Check result of AttachCurrentThread - Sort includes alphabetically - Relax ret_addr_offset() assert - Extra space after if - remove excessive asserts in ProgrammableInvoker::invoke_native - Remove os::is_MP() check - remove blank line in thread.hpp ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/9960b3d7..efc969dc Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=17 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=16-17 Stats: 90 lines in 56 files changed: 14 ins; 13 del; 63 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Tue Nov 10 14:28:06 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Tue, 10 Nov 2020 14:28:06 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 04:10:30 GMT, David Holmes wrote: >> Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 64 commits: >> >> - Merge branch '8254162' into 8254231_linker >> - Fix post-merge issues caused by 8219014 >> - Merge branch 'master' into 8254162 >> - Addess remaining feedback from @AlanBateman and @mrserb >> - Address comments from @AlanBateman >> - Fix typo in upcall helper for aarch64 >> - Merge branch '8254162' into 8254231_linker >> - Merge branch 'master' into 8254162 >> - Fix issues with derived buffers and IO operations >> - More 32-bit fixes for TestLayouts >> - ... and 54 more: https://git.openjdk.java.net/jdk/compare/a50fdd54...b38afb3f > > A high-level scan through - mostly VM files. I've addressed the open review comments. One of the commits is a bigger change that removes the code duplication in the upcall handler code. The initialization code is moved to the ProgrammableUpcallHandler class' constructor instead. That class is then lazily instantiated using a local `static` variable (see ProgrammableUpcallHandler::instance), which since C++11 guarantees thread-safe initialize-once behaviour. Along with those changes I've also removed some other duplicated code in the native invoker code (ProgrammableInvokerGenerator), cleaned up the includes most files, as well as using a JNI_ENTRY function when doing upcalls (as requested), by splitting the current functionality of the upcall_helper function in 2; one function that does the thread attach, and then other that does the actual upcall (which is the one using JNI_ENTRY). (see: https://github.com/openjdk/jdk/pull/634/commits/719224ca9dc70fce6d28885acfb362fee715ebbd). As discussed, changing ProgrammableUpcallHandler to be a well-known class didn't work, since it is not in java.base. Changes: - Merge both versions of upcall_init and move the code to (the constructor of) ProgrammableUpcallHandler. Using the same lazy singleton pattern as for ForeignGlobals to make initialization thread-safe. - Merge both PorgrammableInvokeGenerator classes into a shared ProgrammableInvoke::Generator class. - Also move ProgrammableStub to ProgrammableInvoke::Stub for better name-spacing - Also move native_invoker_size constant to ProgrammableInvoker (we now have 1 instead of 2) - Merge ProgrammableInvoker::Generator::generate and top-level generate_invoke_native functions (avoiding the need to forward fields) - Split upcall_helper method into ProgrammableUpcallHandler::attach_thread_and_do_upcall and upcall_helper. The former does the thread attach/detach, the latter does the actual upcall. - Add a few comments to ProgrammableUpcallHandler::generate_upcall_stub - Remove unused imports The rest of the review comments were addressed in a set of smaller commits (see timeline on GitHub). The changes therein are: - remove blank line in thread.hpp - Remove os::is_MP() check - remove excessive asserts in ProgrammableInvoker::invoke_native - Extra space after if in jni_util_md (Windows) - Relax ret_addr_offset() assert - Sort includes alphabetically in upcallHandler CPU files - Check result of AttachCurrentThread call - Set copyright year for added files to 2020 (I didn't touch the ARM copyright headers) That should address all open review comments (but please let me know if I've missed something). Thanks for the reviews so far. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From github.com+70745465+pkumaraswamy at openjdk.java.net Tue Nov 10 16:10:10 2020 From: github.com+70745465+pkumaraswamy at openjdk.java.net (Prajwal Kumaraswamy) Date: Tue, 10 Nov 2020 16:10:10 GMT Subject: RFR: 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() Message-ID: ?ineResolveURI(). Actual fix looks like this, due to git diff there are lot of changes( mostly because of the spaces) being displayed. --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java @@ -500,6 +500,7 @@ } boolean secVal = Utils.secureValidation(context); + try { xi.setSecureValidation(secVal); if (context instanceof XMLSignContext && c14n11 && !xi.isOctetStream() && !xi.isOutputStreamSet()) { @@ -533,6 +534,11 @@ } else { xi.updateOutputStream(os); } + } finally { + if(xi.getOctetStreamReal() != null) { + xi.getOctetStreamReal().close(); + } + } } ------------- Commit messages: - 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI(). Changes: https://git.openjdk.java.net/jdk/pull/1142/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1142&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8255559 Stats: 44 lines in 1 file changed: 17 ins; 11 del; 16 mod Patch: https://git.openjdk.java.net/jdk/pull/1142.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1142/head:pull/1142 PR: https://git.openjdk.java.net/jdk/pull/1142 From weijun at openjdk.java.net Tue Nov 10 16:10:10 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 10 Nov 2020 16:10:10 GMT Subject: RFR: 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() In-Reply-To: References: Message-ID: On Tue, 10 Nov 2020 11:37:04 GMT, Prajwal Kumaraswamy wrote: > ?ineResolveURI(). > > Actual fix looks like this, due to git diff there are lot of changes( mostly because of the spaces) being displayed. > > --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java > +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java > @@ -500,6 +500,7 @@ > } > > boolean secVal = Utils.secureValidation(context); > + try { > xi.setSecureValidation(secVal); > if (context instanceof XMLSignContext && c14n11 > && !xi.isOctetStream() && !xi.isOutputStreamSet()) { > @@ -533,6 +534,11 @@ > } else { > xi.updateOutputStream(os); > } > + } finally { > + if(xi.getOctetStreamReal() != null) { > + xi.getOctetStreamReal().close(); > + } > + } > } FYI: https://github.com/apache/santuario-xml-security-java/pull/9/files ------------- PR: https://git.openjdk.java.net/jdk/pull/1142 From github.com+70745465+pkumaraswamy at openjdk.java.net Tue Nov 10 16:10:10 2020 From: github.com+70745465+pkumaraswamy at openjdk.java.net (Prajwal Kumaraswamy) Date: Tue, 10 Nov 2020 16:10:10 GMT Subject: RFR: 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() In-Reply-To: References: Message-ID: <9BDZRTwUXwAIKsx5R94oD5GlS9MsvuhMxpRZoO6dCtE=.89536adb-2834-45d6-8693-be996d708b4e@github.com> On Tue, 10 Nov 2020 13:26:01 GMT, Weijun Wang wrote: >> ?ineResolveURI(). >> >> Actual fix looks like this, due to git diff there are lot of changes( mostly because of the spaces) being displayed. >> >> --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java >> +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java >> @@ -500,6 +500,7 @@ >> } >> >> boolean secVal = Utils.secureValidation(context); >> + try { >> xi.setSecureValidation(secVal); >> if (context instanceof XMLSignContext && c14n11 >> && !xi.isOctetStream() && !xi.isOutputStreamSet()) { >> @@ -533,6 +534,11 @@ >> } else { >> xi.updateOutputStream(os); >> } >> + } finally { >> + if(xi.getOctetStreamReal() != null) { >> + xi.getOctetStreamReal().close(); >> + } >> + } >> } > > FYI: https://github.com/apache/santuario-xml-security-java/pull/9/files Thanks Max, I guess there are additional changes in Apache code and will sync our code base with same changes. I'll make appropriate changes and push it again. ------------- PR: https://git.openjdk.java.net/jdk/pull/1142 From weijun at openjdk.java.net Tue Nov 10 17:18:57 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 10 Nov 2020 17:18:57 GMT Subject: RFR: 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() In-Reply-To: References: Message-ID: On Tue, 10 Nov 2020 11:37:04 GMT, Prajwal Kumaraswamy wrote: > ?ineResolveURI(). > > Actual fix looks like this, due to git diff there are lot of changes( mostly because of the spaces) being displayed. > > --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java > +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java > @@ -500,6 +500,7 @@ > } > > boolean secVal = Utils.secureValidation(context); > + try { > xi.setSecureValidation(secVal); > if (context instanceof XMLSignContext && c14n11 > && !xi.isOctetStream() && !xi.isOutputStreamSet()) { > @@ -533,6 +534,11 @@ > } else { > xi.updateOutputStream(os); > } > + } finally { > + if(xi.getOctetStreamReal() != null) { > + xi.getOctetStreamReal().close(); > + } > + } > } Marked as reviewed by weijun (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1142 From weijun at openjdk.java.net Tue Nov 10 17:18:57 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 10 Nov 2020 17:18:57 GMT Subject: RFR: 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() In-Reply-To: References: Message-ID: On Tue, 10 Nov 2020 17:14:42 GMT, Weijun Wang wrote: >> ?ineResolveURI(). >> >> Actual fix looks like this, due to git diff there are lot of changes( mostly because of the spaces) being displayed. >> >> --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java >> +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java >> @@ -500,6 +500,7 @@ >> } >> >> boolean secVal = Utils.secureValidation(context); >> + try { >> xi.setSecureValidation(secVal); >> if (context instanceof XMLSignContext && c14n11 >> && !xi.isOctetStream() && !xi.isOutputStreamSet()) { >> @@ -533,6 +534,11 @@ >> } else { >> xi.updateOutputStream(os); >> } >> + } finally { >> + if(xi.getOctetStreamReal() != null) { >> + xi.getOctetStreamReal().close(); >> + } >> + } >> } > > Marked as reviewed by weijun (Reviewer). > Thanks Max, I guess there are additional changes in Apache code and will sync our code base with same changes. > I'll make appropriate changes and push it again. No worry. Next time we sync with Santuario, when I found the problem is already fixed upstream, our patch will not be applied. ------------- PR: https://git.openjdk.java.net/jdk/pull/1142 From coleenp at openjdk.java.net Tue Nov 10 21:25:06 2020 From: coleenp at openjdk.java.net (Coleen Phillimore) Date: Tue, 10 Nov 2020 21:25:06 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 16:31:23 GMT, Jorn Vernee wrote: >> src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 121: >> >>> 119: upcall_info.upcall_method.name, upcall_info.upcall_method.sig, >>> 120: &args, thread); >>> 121: } >> >> This code shouldn't be in the cpu directory. This should be in SharedRuntime or in jni.cpp. It should have a JNI_ENTRY and not transition directly. I don't know what AttachCurrentThreadAsDaemon does. > > Roger that. > > We need the thread state transition though in case we get a random native thread calling us. yikes. Does that work? ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From coleenp at openjdk.java.net Tue Nov 10 21:37:06 2020 From: coleenp at openjdk.java.net (Coleen Phillimore) Date: Tue, 10 Nov 2020 21:37:06 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Tue, 10 Nov 2020 14:16:22 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: > > - Merge pull request #7 from JornVernee/Additional_Review_Comments > > Additional review comments > - Revert System.java changes > - Set copyright year for added files to 2020 > - Check result of AttachCurrentThread > - Sort includes alphabetically > - Relax ret_addr_offset() assert > - Extra space after if > - remove excessive asserts in ProgrammableInvoker::invoke_native > - Remove os::is_MP() check > - remove blank line in thread.hpp The Hotspot prims and runtime changes look good to me. src/hotspot/share/prims/universalUpcallHandler.cpp line 68: > 66: vm->functions->DetachCurrentThread(vm); > 67: } > 68: } Yes, this looks good. Thanks for moving this. src/hotspot/share/prims/universalUpcallHandler.cpp line 85: > 83: upcall_method.sig = SymbolTable::new_symbol("(L" FOREIGN_ABI "ProgrammableUpcallHandler;J)V"); > 84: > 85: assert(upcall_method.klass->lookup_method(upcall_method.name, upcall_method.sig) != nullptr, I think you need a ResourceMark here. ------------- Marked as reviewed by coleenp (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/634 From dholmes at openjdk.java.net Wed Nov 11 07:24:07 2020 From: dholmes at openjdk.java.net (David Holmes) Date: Wed, 11 Nov 2020 07:24:07 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Tue, 10 Nov 2020 14:16:22 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: > > - Merge pull request #7 from JornVernee/Additional_Review_Comments > > Additional review comments > - Revert System.java changes > - Set copyright year for added files to 2020 > - Check result of AttachCurrentThread > - Sort includes alphabetically > - Relax ret_addr_offset() assert > - Extra space after if > - remove excessive asserts in ProgrammableInvoker::invoke_native > - Remove os::is_MP() check > - remove blank line in thread.hpp Updates seem fine to me. Thanks. Adding approval for hotspot parts. src/hotspot/share/prims/universalUpcallHandler.cpp line 55: > 53: JavaVM_ *vm = (JavaVM *)(&main_vm); > 54: jint result = vm->functions->AttachCurrentThread(vm, (void**) &p_env, nullptr); > 55: guarantee(result == JNI_OK, "Could not attach thread for upcall. JNI error code: %d", result); I'm assuming you don't have a mechanism for conveying an error back to the original entry point used by the native thread? Attaching an existing thread should only fail if we run out of C-Heap, so we're on the brink of aborting anyway, but still the guarantee here is not ideal. ------------- Marked as reviewed by dholmes (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/634 From github.com+70745465+pkumaraswamy at openjdk.java.net Wed Nov 11 09:27:56 2020 From: github.com+70745465+pkumaraswamy at openjdk.java.net (Prajwal Kumaraswamy) Date: Wed, 11 Nov 2020 09:27:56 GMT Subject: Integrated: 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() In-Reply-To: References: Message-ID: <-UqkUi7O2dPp7sFvNwETvep4FZmZFGXFmOuCKeVt9ak=.e5ccef1c-0e9c-4081-b9a4-fc9af838ccc3@github.com> On Tue, 10 Nov 2020 11:37:04 GMT, Prajwal Kumaraswamy wrote: > ?ineResolveURI(). > > Actual fix looks like this, due to git diff there are lot of changes( mostly because of the spaces) being displayed. > > --- a/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java > +++ b/src/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java > @@ -500,6 +500,7 @@ > } > > boolean secVal = Utils.secureValidation(context); > + try { > xi.setSecureValidation(secVal); > if (context instanceof XMLSignContext && c14n11 > && !xi.isOctetStream() && !xi.isOutputStreamSet()) { > @@ -533,6 +534,11 @@ > } else { > xi.updateOutputStream(os); > } > + } finally { > + if(xi.getOctetStreamReal() != null) { > + xi.getOctetStreamReal().close(); > + } > + } > } This pull request has now been integrated. Changeset: 6e8b8628 Author: prajwal_kumaraswamy Committer: Sean Coffey URL: https://git.openjdk.java.net/jdk/commit/6e8b8628 Stats: 44 lines in 1 file changed: 17 ins; 11 del; 16 mod 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() Reviewed-by: weijun ------------- PR: https://git.openjdk.java.net/jdk/pull/1142 From jvernee at openjdk.java.net Wed Nov 11 11:19:04 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Wed, 11 Nov 2020 11:19:04 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 07:18:33 GMT, David Holmes wrote: >> Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: >> >> - Merge pull request #7 from JornVernee/Additional_Review_Comments >> >> Additional review comments >> - Revert System.java changes >> - Set copyright year for added files to 2020 >> - Check result of AttachCurrentThread >> - Sort includes alphabetically >> - Relax ret_addr_offset() assert >> - Extra space after if >> - remove excessive asserts in ProgrammableInvoker::invoke_native >> - Remove os::is_MP() check >> - remove blank line in thread.hpp > > src/hotspot/share/prims/universalUpcallHandler.cpp line 55: > >> 53: JavaVM_ *vm = (JavaVM *)(&main_vm); >> 54: jint result = vm->functions->AttachCurrentThread(vm, (void**) &p_env, nullptr); >> 55: guarantee(result == JNI_OK, "Could not attach thread for upcall. JNI error code: %d", result); > > I'm assuming you don't have a mechanism for conveying an error back to the original entry point used by the native thread? Attaching an existing thread should only fail if we run out of C-Heap, so we're on the brink of aborting anyway, but still the guarantee here is not ideal. Yeah, we have no idea where/how to report such and error. The native code might just call a function through a function pointer like `void(*)(void)` i.e. no place to return an error code. Also, since it's a previously non-attached thread, there is no JavaFrameAnchor that gives us a last Java frame we could jump back to and throw an exception. Is there's a more explicit way to exit with an error, other than a `guarantee` that you would prefer here? ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From david.holmes at oracle.com Wed Nov 11 11:36:43 2020 From: david.holmes at oracle.com (David Holmes) Date: Wed, 11 Nov 2020 21:36:43 +1000 Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: <718dab9a-2939-68a6-9c79-2414a7296ffe@oracle.com> On 11/11/2020 9:19 pm, Jorn Vernee wrote: > On Wed, 11 Nov 2020 07:18:33 GMT, David Holmes wrote: > >>> Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: >>> >>> - Merge pull request #7 from JornVernee/Additional_Review_Comments >>> >>> Additional review comments >>> - Revert System.java changes >>> - Set copyright year for added files to 2020 >>> - Check result of AttachCurrentThread >>> - Sort includes alphabetically >>> - Relax ret_addr_offset() assert >>> - Extra space after if >>> - remove excessive asserts in ProgrammableInvoker::invoke_native >>> - Remove os::is_MP() check >>> - remove blank line in thread.hpp >> >> src/hotspot/share/prims/universalUpcallHandler.cpp line 55: >> >>> 53: JavaVM_ *vm = (JavaVM *)(&main_vm); >>> 54: jint result = vm->functions->AttachCurrentThread(vm, (void**) &p_env, nullptr); >>> 55: guarantee(result == JNI_OK, "Could not attach thread for upcall. JNI error code: %d", result); >> >> I'm assuming you don't have a mechanism for conveying an error back to the original entry point used by the native thread? Attaching an existing thread should only fail if we run out of C-Heap, so we're on the brink of aborting anyway, but still the guarantee here is not ideal. > > Yeah, we have no idea where/how to report such and error. The native code might just call a function through a function pointer like `void(*)(void)` i.e. no place to return an error code. Also, since it's a previously non-attached thread, there is no JavaFrameAnchor that gives us a last Java frame we could jump back to and throw an exception. Yeah not a solvable problem when you can transparently attach to the VM. > Is there's a more explicit way to exit with an error, other than a `guarantee` that you would prefer here? Perhaps vm_exit_out_if_memory under the assumption that is the only reason attach could fail. But really I don't think it makes much practical difference. Thanks, David ----- > ------------- > > PR: https://git.openjdk.java.net/jdk/pull/634 > From mcimadamore at openjdk.java.net Wed Nov 11 11:40:12 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Wed, 11 Nov 2020 11:40:12 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v27] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 34 commits: - Merge branch 'master' into 8254162 - Add more output in TestHandhsake.java - Further improve output of TestHandshake - Improve debugging output of TestHandhsake - Remove endianness-aware byte getter/setter in MemoryAccess Remove index-based version of byte getter/setter in MemoryAccess - Fix post-merge issues caused by 8219014 - Merge branch 'master' into 8254162 - Addess remaining feedback from @AlanBateman and @mrserb - Address comments from @AlanBateman - Merge branch 'master' into 8254162 - ... and 24 more: https://git.openjdk.java.net/jdk/compare/432c387e...8444c633 ------------- Changes: https://git.openjdk.java.net/jdk/pull/548/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=26 Stats: 7600 lines in 82 files changed: 4791 ins; 1590 del; 1219 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From mcimadamore at openjdk.java.net Wed Nov 11 11:50:14 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Wed, 11 Nov 2020 11:50:14 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v28] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Invert condition in memory access var handle `withInvokeBehavior' ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/548/files - new: https://git.openjdk.java.net/jdk/pull/548/files/8444c633..eae57b4d Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=27 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=26-27 Stats: 2 lines in 1 file changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From dnsimon at openjdk.java.net Wed Nov 11 13:28:03 2020 From: dnsimon at openjdk.java.net (Doug Simon) Date: Wed, 11 Nov 2020 13:28:03 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Mon, 9 Nov 2020 11:50:54 GMT, Jorn Vernee wrote: >> src/hotspot/cpu/aarch64/universalUpcallHandler_aarch64.cpp line 99: >> >>> 97: if (thread == NULL) { >>> 98: JavaVM_ *vm = (JavaVM *)(&main_vm); >>> 99: vm -> functions -> AttachCurrentThreadAsDaemon(vm, &p_env, NULL); >> >> Style nit: don't put spaces around `->` operator. >> >> What is the context for this being called? It looks highly suspicious to just attach the current thread to the VM this way. > > The context is a thread that is spawned by native code doing an upcall. We need to attach the thread to the VM first in that case. Normally this would be handled by the calling code, but in our case the calling code doesn't know it's calling into Java. Where's the logic for the native thread to detach? We have a similar problem in libgraal. We have a [utility class](https://github.com/oracle/graal/blob/e4b9ab931940e1946f96f2015b937ba100384573/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java#L27-L32) for libgraal created threads (as opposed to VM created threads that call into libgraal) that call into the VM. The utility class takes care of [attaching](https://github.com/oracle/graal/blob/a913944a06425c25ccd6e4a90379938fcf7ea2cf/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java#L749) and [detaching](https://github.com/oracle/graal/blob/a913944a06425c25ccd6e4a90379938fcf7ea2cf/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java#L757) to/from the VM. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Wed Nov 11 13:34:02 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Wed, 11 Nov 2020 13:34:02 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 13:25:32 GMT, Doug Simon wrote: >> The context is a thread that is spawned by native code doing an upcall. We need to attach the thread to the VM first in that case. Normally this would be handled by the calling code, but in our case the calling code doesn't know it's calling into Java. > > Where's the logic for the native thread to detach? We have a similar problem in libgraal. We have a [utility class](https://github.com/oracle/graal/blob/e4b9ab931940e1946f96f2015b937ba100384573/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java#L27-L32) for libgraal created threads (as opposed to VM created threads that call into libgraal) that call into the VM. The utility class takes care of [attaching](https://github.com/oracle/graal/blob/a913944a06425c25ccd6e4a90379938fcf7ea2cf/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java#L749) and [detaching](https://github.com/oracle/graal/blob/a913944a06425c25ccd6e4a90379938fcf7ea2cf/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java#L757) to/from the VM. I added a call to DetachCurrentThread here: https://github.com/openjdk/jdk/pull/634/commits/719224ca9dc70fce6d28885acfb362fee715ebbd#diff-c084afc373a6ce95010a480ddc5ab79d3cb759b80e46102c212c2cbc948e2303R65 ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From dnsimon at openjdk.java.net Wed Nov 11 14:00:14 2020 From: dnsimon at openjdk.java.net (Doug Simon) Date: Wed, 11 Nov 2020 14:00:14 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v15] In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 13:31:11 GMT, Jorn Vernee wrote: >> Where's the logic for the native thread to detach? We have a similar problem in libgraal. We have a [utility class](https://github.com/oracle/graal/blob/e4b9ab931940e1946f96f2015b937ba100384573/compiler/src/org.graalvm.compiler.core/src/org/graalvm/compiler/core/GraalServiceThread.java#L27-L32) for libgraal created threads (as opposed to VM created threads that call into libgraal) that call into the VM. The utility class takes care of [attaching](https://github.com/oracle/graal/blob/a913944a06425c25ccd6e4a90379938fcf7ea2cf/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java#L749) and [detaching](https://github.com/oracle/graal/blob/a913944a06425c25ccd6e4a90379938fcf7ea2cf/substratevm/src/com.oracle.svm.graal.hotspot.libgraal/src/com/oracle/svm/graal/hotspot/libgraal/LibGraalFeature.java#L757) to/from the VM. > > I added a call to DetachCurrentThread here: https://github.com/openjdk/jdk/pull/634/commits/719224ca9dc70fce6d28885acfb362fee715ebbd#diff-c084afc373a6ce95010a480ddc5ab79d3cb759b80e46102c212c2cbc948e2303R65 Ok. That makes for high overhead for each upcall on a non-attached native thread. I assume that's an edge case not worth optimizing? ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From vlivanov at openjdk.java.net Wed Nov 11 14:21:14 2020 From: vlivanov at openjdk.java.net (Vladimir Ivanov) Date: Wed, 11 Nov 2020 14:21:14 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Tue, 10 Nov 2020 14:16:22 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: > > - Merge pull request #7 from JornVernee/Additional_Review_Comments > > Additional review comments > - Revert System.java changes > - Set copyright year for added files to 2020 > - Check result of AttachCurrentThread > - Sort includes alphabetically > - Relax ret_addr_offset() assert > - Extra space after if > - remove excessive asserts in ProgrammableInvoker::invoke_native > - Remove os::is_MP() check > - remove blank line in thread.hpp I made a pass over hotspot code. Overall, it looks good. Some comments follow. src/hotspot/cpu/aarch64/vmreg_aarch64.cpp line 57: > 55: #define INTEGER_TYPE 0 > 56: #define VECTOR_TYPE 1 > 57: #define X87_TYPE 2 Unused. src/hotspot/cpu/aarch64/foreign_globals_aarch64.hpp line 31: > 29: #include "utilities/growableArray.hpp" > 30: > 31: #define __ _masm-> Should be declared in cpp file instead. src/hotspot/cpu/x86/foreign_globals_x86.hpp line 30: > 28: #include "utilities/growableArray.hpp" > 29: > 30: #define __ _masm-> Same here (move to cpp file). src/hotspot/share/opto/lcm.cpp line 867: > 865: case Op_CallNative: > 866: // FIXME compute actual save policy based on nep->abi > 867: save_policy = _matcher._c_reg_save_policy; Please, elaborate here why it's OK for now to use ` _c_reg_save_policy`. And then turn `FIXME` into `TODO`. If possible, would be nice to introduce some asserts to back the claim. src/hotspot/share/opto/machnode.cpp line 831: > 829: st->print("%s ",_name); > 830: st->print("_arg_regs: "); > 831: _arg_regs.print_on(st); It doesn't print any useful info: `_arg_regs: AllocatedObj(0x000000011cf5cbe8)`. Please, improve it. src/hotspot/share/opto/output.cpp line 3394: > 3392: } > 3393: > 3394: address* native_stubs = NULL; IMO it's worth considering inlining `native_stubs` array into `nmethod` itself. That's the way how per-nmethod information is handled now (e.g., dependencies, debug info, exception handler table, implicit exception table). src/hotspot/share/opto/callnode.cpp line 1184: > 1182: void CallNativeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const { > 1183: assert((tf()->domain()->cnt() - TypeFunc::Parms) == argcnt, "arg counts must match!"); > 1184: #ifndef PRODUCT Should be `#ifdef ASSERT` instead. src/hotspot/share/opto/callnode.cpp line 1143: > 1141: case TypeFunc::Parms: > 1142: default: { > 1143: if(tf()->range()->field_at(proj->_con) == Type::HALF) { That's `TypeFunc::Parms+1` case in `CallNode::match`. Why did you decide to move it to `default` case? Overall, it looks very similar to `CallNode::match`. Why not just customize `OptoRegPair regs` computation for `CallNative` there? src/hotspot/share/opto/graphKit.cpp line 2665: > 2663: for (uint vm_ret_pos = 0; vm_ret_pos < n_returns; vm_ret_pos++) { > 2664: if (new_call_type->range()->field_at(TypeFunc::Parms + vm_ret_pos) == Type::HALF) { > 2665: // FIXME is this needed? Why do you need the projection at all? Please, clarify and remove `FIXME` comment. src/hotspot/share/opto/graphKit.cpp line 2675: > 2673: // Unpack native results if needed > 2674: // Need this method type since it's unerased > 2675: switch (nep->method_type()->rtype()->basic_type()) { Are calls returning multiple values supported right now? (From what I'm seeing in other places, they are not supported.) If not, then you don't need a loop over return values and there are other places where it can simplify code. src/hotspot/share/opto/type.hpp line 678: > 676: static const TypeTuple *make_range(ciSignature *sig); > 677: static const TypeTuple *make_domain(ciInstanceKlass* recv, ciSignature *sig); > 678: static const TypeTuple *make_func(uint arg_cnt, const Type **arg_fields); I find `make_func` name misleading: it makes an impression you get `TypeFunc` out of it, but in reailty it just composes type array with `TypeTyple::make`+`TypeTyple::fields`. I'd prefer to see it as `TypeTuple::fields` overload. Or rewrite `GraphKit::make_native_call` to operate directly on `TypeTyple::fields` and get rid fo intermediate arrays. src/hotspot/share/opto/output.cpp line 1144: > 1142: methodHandle null_mh; > 1143: bool rethrow_exception = false; > 1144: bool is_opt_native = mach->is_MachCallNative(); Please, move it to `MachCall`-related logic (where `is_method_handle_invoke` is set). src/hotspot/cpu/x86/universalNativeInvoker_x86.cpp line 77: > 75: XMMRegister reg = _abi->_vector_argument_registers.at(i); > 76: size_t offs = _layout->arguments_vector + i * sizeof(VectorRegister); > 77: if (UseAVX >= 3) { Assuming worst-case scenario (w.r.t. value size) is sub-optimal. Considering FP values are handled as vectors you end up operating on 32-bit/64-bit values as if they were 512-bit in size. And, in addition to wasted memory bandwidth, EVEX-encoded instructions may trigger CPU frequency scaling which will penalize cases when AVX512 is not used. So, it is worth considering annotating vector values with their actual sizes and taking the size into account when operating on vectors. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From clanger at openjdk.java.net Wed Nov 11 14:42:09 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Wed, 11 Nov 2020 14:42:09 GMT Subject: RFR: 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest Message-ID: Working on 11u backports of JDK-8218021 and JDK-8250968, I found some minor points for improvement in tests test/jdk/sun/security/tools/jarsigner/PosixPermissionsTest.java and test/jdk/sun/security/tools/jarsigner/SymLinkTest.java The details PosixPermissionsTest: - it can run on any system, no matter if the default filesystem supports Posix or not since Posix support is only required for the zipfs which is always true. - improve some comments for the test flow SymLinkTest: - make output of createByteArray prettier - improve inline comments to ease understanding - add an option to main for generating ZIPBYTES - use "Files.write(Path.of(ZIPFILENAME), ZIPBYTES)" for creating the test zipfile ------------- Commit messages: - 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest Changes: https://git.openjdk.java.net/jdk/pull/1166/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1166&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256202 Stats: 91 lines in 2 files changed: 34 ins; 7 del; 50 mod Patch: https://git.openjdk.java.net/jdk/pull/1166.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1166/head:pull/1166 PR: https://git.openjdk.java.net/jdk/pull/1166 From jvernee at openjdk.java.net Wed Nov 11 14:42:12 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Wed, 11 Nov 2020 14:42:12 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 12:44:56 GMT, Vladimir Ivanov wrote: >> Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: >> >> - Merge pull request #7 from JornVernee/Additional_Review_Comments >> >> Additional review comments >> - Revert System.java changes >> - Set copyright year for added files to 2020 >> - Check result of AttachCurrentThread >> - Sort includes alphabetically >> - Relax ret_addr_offset() assert >> - Extra space after if >> - remove excessive asserts in ProgrammableInvoker::invoke_native >> - Remove os::is_MP() check >> - remove blank line in thread.hpp > > src/hotspot/share/opto/callnode.cpp line 1143: > >> 1141: case TypeFunc::Parms: >> 1142: default: { >> 1143: if(tf()->range()->field_at(proj->_con) == Type::HALF) { > > That's `TypeFunc::Parms+1` case in `CallNode::match`. Why did you decide to move it to `default` case? > > Overall, it looks very similar to `CallNode::match`. Why not just customize `OptoRegPair regs` computation for `CallNative` there? For native calls we can have multiple return values, at least in theory. Currently this is not the case though. Will take another look. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Wed Nov 11 14:48:04 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Wed, 11 Nov 2020 14:48:04 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 14:17:20 GMT, Vladimir Ivanov wrote: >> Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: >> >> - Merge pull request #7 from JornVernee/Additional_Review_Comments >> >> Additional review comments >> - Revert System.java changes >> - Set copyright year for added files to 2020 >> - Check result of AttachCurrentThread >> - Sort includes alphabetically >> - Relax ret_addr_offset() assert >> - Extra space after if >> - remove excessive asserts in ProgrammableInvoker::invoke_native >> - Remove os::is_MP() check >> - remove blank line in thread.hpp > > src/hotspot/cpu/x86/universalNativeInvoker_x86.cpp line 77: > >> 75: XMMRegister reg = _abi->_vector_argument_registers.at(i); >> 76: size_t offs = _layout->arguments_vector + i * sizeof(VectorRegister); >> 77: if (UseAVX >= 3) { > > Assuming worst-case scenario (w.r.t. value size) is sub-optimal. Considering FP values are handled as vectors you end up operating on 32-bit/64-bit values as if they were 512-bit in size. And, in addition to wasted memory bandwidth, EVEX-encoded instructions may trigger CPU frequency scaling which will penalize cases when AVX512 is not used. So, it is worth considering annotating vector values with their actual sizes and taking the size into account when operating on vectors. Yes, more cleanup is needed here. We don't support vectors at all right now, so I'd rather remove this code and only operate on XMM registers instead. In the future this could be handled using separate VMStorage types for different vector sizes. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From jvernee at openjdk.java.net Wed Nov 11 15:36:11 2020 From: jvernee at openjdk.java.net (Jorn Vernee) Date: Wed, 11 Nov 2020 15:36:11 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 11:05:47 GMT, Vladimir Ivanov wrote: >> Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: >> >> - Merge pull request #7 from JornVernee/Additional_Review_Comments >> >> Additional review comments >> - Revert System.java changes >> - Set copyright year for added files to 2020 >> - Check result of AttachCurrentThread >> - Sort includes alphabetically >> - Relax ret_addr_offset() assert >> - Extra space after if >> - remove excessive asserts in ProgrammableInvoker::invoke_native >> - Remove os::is_MP() check >> - remove blank line in thread.hpp > > src/hotspot/share/opto/machnode.cpp line 831: > >> 829: st->print("%s ",_name); >> 830: st->print("_arg_regs: "); >> 831: _arg_regs.print_on(st); > > It doesn't print any useful info: `_arg_regs: AllocatedObj(0x000000011cf5cbe8)`. Please, improve it. Ok, I added printing to GrowableArray at some point, but seems that this was removed in a merge maybe. > src/hotspot/share/opto/graphKit.cpp line 2665: > >> 2663: for (uint vm_ret_pos = 0; vm_ret_pos < n_returns; vm_ret_pos++) { >> 2664: if (new_call_type->range()->field_at(TypeFunc::Parms + vm_ret_pos) == Type::HALF) { >> 2665: // FIXME is this needed? > > Why do you need the projection at all? Please, clarify and remove `FIXME` comment. Was a leftover. Will remove > src/hotspot/share/opto/graphKit.cpp line 2675: > >> 2673: // Unpack native results if needed >> 2674: // Need this method type since it's unerased >> 2675: switch (nep->method_type()->rtype()->basic_type()) { > > Are calls returning multiple values supported right now? (From what I'm seeing in other places, they are not supported.) If not, then you don't need a loop over return values and there are other places where it can simplify code. Yes, multiple returns are not supported currently. Will simplify this. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From mbaesken at openjdk.java.net Thu Nov 12 06:46:55 2020 From: mbaesken at openjdk.java.net (Matthias Baesken) Date: Thu, 12 Nov 2020 06:46:55 GMT Subject: RFR: 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 14:36:07 GMT, Christoph Langer wrote: > Working on 11u backports of JDK-8218021 and JDK-8250968, I found some minor points for improvement in tests > test/jdk/sun/security/tools/jarsigner/PosixPermissionsTest.java and > test/jdk/sun/security/tools/jarsigner/SymLinkTest.java > > The details > > PosixPermissionsTest: > - it can run on any system, no matter if the default filesystem supports Posix or not since Posix support is only required for the zipfs which is always true. > - improve some comments for the test flow > > SymLinkTest: > - make output of createByteArray prettier > - improve inline comments to ease understanding > - add an option to main for generating ZIPBYTES > - use "Files.write(Path.of(ZIPFILENAME), ZIPBYTES)" for creating the test zipfile Marked as reviewed by mbaesken (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1166 From mbaesken at openjdk.java.net Thu Nov 12 06:46:56 2020 From: mbaesken at openjdk.java.net (Matthias Baesken) Date: Thu, 12 Nov 2020 06:46:56 GMT Subject: RFR: 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 06:44:10 GMT, Matthias Baesken wrote: >> Working on 11u backports of JDK-8218021 and JDK-8250968, I found some minor points for improvement in tests >> test/jdk/sun/security/tools/jarsigner/PosixPermissionsTest.java and >> test/jdk/sun/security/tools/jarsigner/SymLinkTest.java >> >> The details >> >> PosixPermissionsTest: >> - it can run on any system, no matter if the default filesystem supports Posix or not since Posix support is only required for the zipfs which is always true. >> - improve some comments for the test flow >> >> SymLinkTest: >> - make output of createByteArray prettier >> - improve inline comments to ease understanding >> - add an option to main for generating ZIPBYTES >> - use "Files.write(Path.of(ZIPFILENAME), ZIPBYTES)" for creating the test zipfile > > Marked as reviewed by mbaesken (Reviewer). Looks good to me ! ------------- PR: https://git.openjdk.java.net/jdk/pull/1166 From mcimadamore at openjdk.java.net Thu Nov 12 12:18:09 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 12 Nov 2020 12:18:09 GMT Subject: RFR: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) [v29] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 36 commits: - Merge branch 'master' into 8254162 - Invert condition in memory access var handle `withInvokeBehavior' - Merge branch 'master' into 8254162 - Add more output in TestHandhsake.java - Further improve output of TestHandshake - Improve debugging output of TestHandhsake - Remove endianness-aware byte getter/setter in MemoryAccess Remove index-based version of byte getter/setter in MemoryAccess - Fix post-merge issues caused by 8219014 - Merge branch 'master' into 8254162 - Addess remaining feedback from @AlanBateman and @mrserb - ... and 26 more: https://git.openjdk.java.net/jdk/compare/ec08b3f2...0b81a39e ------------- Changes: https://git.openjdk.java.net/jdk/pull/548/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=548&range=28 Stats: 7600 lines in 82 files changed: 4791 ins; 1590 del; 1219 mod Patch: https://git.openjdk.java.net/jdk/pull/548.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/548/head:pull/548 PR: https://git.openjdk.java.net/jdk/pull/548 From xuelei at openjdk.java.net Thu Nov 12 16:16:59 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Thu, 12 Nov 2020 16:16:59 GMT Subject: RFR: 8255546: Missing coverage for javax.smartcardio.CardPermission and ResponseAPDU In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 12:04:20 GMT, Fernando Guallini wrote: > This patch is to add code coverage to the following methods > - javax.smartcardio.CardPermission::**implies** (1) > - javax.smartcardio.ResponseAPDU::**toString** (2) > > Tests are added following the expected implementation given in the methods specifications > > (1) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java#L214-L229 > > (2) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/ResponseAPDU.java#L141-L149 Marked as reviewed by xuelei (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1092 From ascarpino at openjdk.java.net Thu Nov 12 16:34:30 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Thu, 12 Nov 2020 16:34:30 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: > 8253821: Improve ByteBuffer performance with GCM Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: Code review comment update Major change to test to detect corruption with incremental buffers test ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/411/files - new: https://git.openjdk.java.net/jdk/pull/411/files/7c54017f..8580c6ec Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=411&range=03 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=411&range=02-03 Stats: 690 lines in 8 files changed: 422 ins; 150 del; 118 mod Patch: https://git.openjdk.java.net/jdk/pull/411.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/411/head:pull/411 PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Thu Nov 12 16:37:06 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Thu, 12 Nov 2020 16:37:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: <9IvsxvHGzvQoM756tUBFHLcMyZjvdbevzh7c-I3i6zU=.03c89dcb-a547-4a07-b0db-358fa9b3fe27@github.com> Message-ID: On Fri, 23 Oct 2020 16:35:10 GMT, Anthony Scarpino wrote: >> I will take a look as well. > > This is an update for all of Valerie's comments and adding a test to verify different buffer types and configurations The latest update should address all outstanding comments. The biggest change was to the test, which had major reorganization and created tests that increments data sizes for update and doFinal ops byte-by-byte to check for any errors. That should reduce concerns about buffer corruption. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From mcimadamore at openjdk.java.net Thu Nov 12 16:41:01 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 12 Nov 2020 16:41:01 GMT Subject: Integrated: 8254162: Implementation of Foreign-Memory Access API (Third Incubator) In-Reply-To: References: Message-ID: On Wed, 7 Oct 2020 17:13:22 GMT, Maurizio Cimadamore wrote: > This patch contains the changes associated with the third incubation round of the foreign memory access API incubation (see JEP 393 [1]). This iteration focus on improving the usability of the API in 3 main ways: > > * first, by providing a way to obtain truly *shared* segments, which can be accessed and closed concurrently from multiple threads > * second, by providing a way to register a memory segment against a `Cleaner`, so as to have some (optional) guarantee that the memory will be deallocated, eventually > * third, by not requiring users to dive deep into var handles when they first pick up the API; a new `MemoryAccess` class has been added, which defines several useful dereference routines; these are really just thin wrappers around memory access var handles, but they make the barrier of entry for using this API somewhat lower. > > A big conceptual shift that comes with this API refresh is that the role of `MemorySegment` and `MemoryAddress` is not the same as it used to be; it used to be the case that a memory address could (sometimes, not always) have a back link to the memory segment which originated it; additionally, memory access var handles used `MemoryAddress` as a basic unit of dereference. > > This has all changed as per this API refresh; now a `MemoryAddress` is just a dumb carrier which wraps a pair of object/long addressing coordinates; `MemorySegment` has become the star of the show, as far as dereferencing memory is concerned. You cannot dereference memory if you don't have a segment. This improves usability in a number of ways - first, it is a lot easier to wrap native addresses (`long`, essentially) into a `MemoryAddress`; secondly, it is crystal clear what a client has to do in order to dereference memory: if a client has a segment, it can use that; otherwise, if the client only has an address, it will have to create a segment *unsafely* (this can be done by calling `MemoryAddress::asSegmentRestricted`). > > A list of the API, implementation and test changes is provided below. If you have any questions, or need more detailed explanations, I (and the rest of the Panama team) will be happy to point at existing discussions, and/or to provide the feedback required. > > A big thank to Erik Osterlund, Vladimir Ivanov and David Holmes, without whom the work on shared memory segment would not have been possible; also I'd like to thank Paul Sandoz, whose insights on API design have been very helpful in this journey. > > Thanks > Maurizio > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff: > > http://cr.openjdk.java.net/~mcimadamore/8254162_v1/specdiff/jdk/incubator/foreign/package-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254163 > > > > ### API Changes > > * `MemorySegment` > * drop factory for restricted segment (this has been moved to `MemoryAddress`, see below) > * added a no-arg factory for a native restricted segment representing entire native heap > * rename `withOwnerThread` to `handoff` > * add new `share` method, to create shared segments > * add new `registerCleaner` method, to register a segment against a cleaner > * add more helpers to create arrays from a segment e.g. `toIntArray` > * add some `asSlice` overloads (to make up for the fact that now segments are more frequently used as cursors) > * rename `baseAddress` to `address` (so that `MemorySegment` can implement `Addressable`) > * `MemoryAddress` > * drop `segment` accessor > * drop `rebase` method and replace it with `segmentOffset` which returns the offset (a `long`) of this address relative to a given segment > * `MemoryAccess` > * New class supporting several static dereference helpers; the helpers are organized by carrier and access mode, where a carrier is one of the usual suspect (a Java primitive, minus `boolean`); the access mode can be simple (e.g. access base address of given segment), or indexed, in which case the accessor takes a segment and either a low-level byte offset,or a high level logical index. The classification is reflected in the naming scheme (e.g. `getByte` vs. `getByteAtOffset` vs `getByteAtIndex`). > * `MemoryHandles` > * drop `withOffset` combinator > * drop `withStride` combinator > * the basic memory access handle factory now returns a var handle which takes a `MemorySegment` and a `long` - from which it is easy to derive all the other handles using plain var handle combinators. > * `Addressable` > * This is a new interface which is attached to entities which can be projected to a `MemoryAddress`. For now, both `MemoryAddress` and `MemorySegment` implement it; we have plans, with JEP 389 [2] to add more implementations. Clients can largely ignore this interface, which comes in really handy when defining native bindings with tools like `jextract`. > * `MemoryLayouts` > * A new layout, for machine addresses, has been added to the mix. > > > > ### Implementation changes > > There are two main things to discuss here: support for shared segments, and the general simplification of the memory access var handle support. > > #### Shared segments > > The support for shared segments cuts in pretty deep in the VM. Support for shared segments is notoriously hard to achieve, at least in a way that guarantees optimal access performances. This is caused by the fact that, if a segment is shared, it would be possible for a thread to close it while another is accessing it. > > After considering several options (see [3]), we zeroed onto an approach which is inspired by an happy idea that Andrew Haley had (and that he reminded me of at this year OpenJDK committer workshop - thanks!). The idea is that if we could *freeze* the world (e.g. with a GC pause), while a segment is closed, we could then prevent segments from being accessed concurrently to a close operation. For this to work, it is crucial that no GC safepoints can occur between a segment liveness check and the access itself (otherwise it would be possible for the accessing thread to stop just right before an unsafe call). It also relies on the fact that hotspot/C2 should not be able to propagate loads across safepoints. > > Sadly, none of these conditions seems to be valid in the current implementation, so we needed to resort to a bit of creativity. First, we noted that, if we could mark so called *scoped* method with an annotation, it would be very simply to check as to whether a thread was in the middle of a scoped method when we stopped the world for a close operation (btw, instead of stopping the world, we do a much more efficient, thread-local polling, thanks to JEP 312 [4]). > > The question is, then, once we detect that a thread is accessing the very segment we're about to close, what should happen? We first experimented with a solution which would install an *asynchronous* exception on the accessing thread, thus making it fail. This solution has some desirable properties, in that a `close` operation always succeeds. Unfortunately the machinery for async exceptions is a bit fragile (e.g. not all the code in hotspot checks for async exceptions); to minimize risks, we decided to revert to a simpler strategy, where `close` might fail when it finds that another thread is accessing the segment being closed. > > As written in the javadoc, this doesn't mean that clients should just catch and try again; an exception on `close` is a bug in the user code, likely arising from lack of synchronization, and should be treated as such. > > In terms of gritty implementation, we needed to centralize memory access routines in a single place, so that we could have a set of routines closely mimicking the primitives exposed by `Unsafe` but which, in addition, also provided a liveness check. This way we could mark all these routines with the special `@Scoped` annotation, which tells the VM that something important is going on. > > To achieve this, we created a new (autogenerated) class, called `ScopedMemoryAccess`. This class contains all the main memory access primitives (including bulk access, like `copyMemory`, or `setMemory`), and accepts, in addition to the access coordinates, also a scope object, which is tested before access. A reachability fence is also thrown in the mix to make sure that the scope is kept alive during access (which is important when registering segments against cleaners). > > Of course, to make memory access safe, memory access var handles, byte buffer var handles, and byte buffer API should use the new `ScopedMemoryAccess` class instead of unsafe, so that a liveness check can be triggered (in case a scope is present). > > `ScopedMemoryAccess` has a `closeScope` method, which initiates the thread-local handshakes, and returns `true` if the handshake completed successfully. > > The implementation of `MemoryScope` (now significantly simplified from what we had before), has two implementations, one for confined segments and one for shared segments; the main difference between the two is what happens when the scope is closed; a confined segment sets a boolean flag to false, and returns, whereas a shared segment goes into a `CLOSING` state, then starts the handshake, and then updates the state again, to either `CLOSED` or `ALIVE` depending on whether the handshake was successful or not. Note that when a shared segment is in the `CLOSING` state, `MemorySegment::isAlive` will still return `true`, while the liveness check upon memory access will fail. > > #### Memory access var handles overhaul > > The key realization here was that if all memory access var handles took a coordinate pair of `MemorySegment` and `long`, all other access types could be derived from this basic var handle form. > > This allowed us to remove the on-the-fly var handle generation, and to simply derive structural access var handles (such as those obtained by calling `MemoryLayout::varHandle`) using *plain* var handle combinators, so that e.g. additional offset is injected into a base memory access var handle. > > This also helped in simplifying the implementation by removing the special `withStride` and `withOffset` combinators, which previously needed low-level access on the innards of the memory access var handle. All that code is now gone. > > #### Test changes > > Not much to see here - most of the tests needed to be updated because of the API changes. Some were beefed up (like the array test, since now segments can be projected into many different kinds of arrays). A test has been added to test the `Cleaner` functionality, and another stress test has been added for shared segments (`TestHandshake`). Some of the microbenchmarks also needed some tweaks - and some of them were also updated to also test performance in the shared segment case. > > [1] - https://openjdk.java.net/jeps/393 > [2] - https://openjdk.java.net/jeps/389 > [3] - https://mail.openjdk.java.net/pipermail/panama-dev/2020-May/009004.html > [4] - https://openjdk.java.net/jeps/312 This pull request has now been integrated. Changeset: 3e70aac5 Author: Maurizio Cimadamore URL: https://git.openjdk.java.net/jdk/commit/3e70aac5 Stats: 7600 lines in 82 files changed: 4791 ins; 1590 del; 1219 mod 8254162: Implementation of Foreign-Memory Access API (Third Incubator) Reviewed-by: erikj, psandoz, alanb ------------- PR: https://git.openjdk.java.net/jdk/pull/548 From fguallini at openjdk.java.net Thu Nov 12 17:07:58 2020 From: fguallini at openjdk.java.net (Fernando Guallini) Date: Thu, 12 Nov 2020 17:07:58 GMT Subject: Integrated: 8255546: Missing coverage for javax.smartcardio.CardPermission and ResponseAPDU In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 12:04:20 GMT, Fernando Guallini wrote: > This patch is to add code coverage to the following methods > - javax.smartcardio.CardPermission::**implies** (1) > - javax.smartcardio.ResponseAPDU::**toString** (2) > > Tests are added following the expected implementation given in the methods specifications > > (1) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/CardPermission.java#L214-L229 > > (2) https://github.com/openjdk/jdk/blob/5dfb42fc68099278cbc98e25fb8a91fd957c12e2/src/java.smartcardio/share/classes/javax/smartcardio/ResponseAPDU.java#L141-L149 This pull request has now been integrated. Changeset: 90f9a705 Author: Fernando Guallini Committer: Xue-Lei Andrew Fan URL: https://git.openjdk.java.net/jdk/commit/90f9a705 Stats: 122 lines in 2 files changed: 82 ins; 12 del; 28 mod 8255546: Missing coverage for javax.smartcardio.CardPermission and ResponseAPDU Reviewed-by: xuelei ------------- PR: https://git.openjdk.java.net/jdk/pull/1092 From mcimadamore at openjdk.java.net Thu Nov 12 17:58:21 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 12 Nov 2020 17:58:21 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v19] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 78 commits: - Merge branch 'master' into 8254231_linker - Merge pull request #7 from JornVernee/Additional_Review_Comments Additional review comments - Revert System.java changes - Set copyright year for added files to 2020 - Check result of AttachCurrentThread - Sort includes alphabetically - Relax ret_addr_offset() assert - Extra space after if - remove excessive asserts in ProgrammableInvoker::invoke_native - Remove os::is_MP() check - ... and 68 more: https://git.openjdk.java.net/jdk/compare/3e70aac5...56099dac ------------- Changes: https://git.openjdk.java.net/jdk/pull/634/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=18 Stats: 67452 lines in 213 files changed: 67277 ins; 79 del; 96 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Thu Nov 12 18:07:23 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 12 Nov 2020 18:07:23 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v20] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Fix whitespaces ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/56099dac..e3d62ee7 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=19 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=18-19 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Thu Nov 12 18:07:23 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Thu, 12 Nov 2020 18:07:23 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v18] In-Reply-To: References: Message-ID: <0NZr5QkMAOUHtmbqSuJA8ZUHPZR6D3sO5pQvBneCbf0=.70e86f1c-0217-47b0-bd53-bdb4fa488800@github.com> On Wed, 11 Nov 2020 14:18:33 GMT, Vladimir Ivanov wrote: >> Maurizio Cimadamore has updated the pull request incrementally with 10 additional commits since the last revision: >> >> - Merge pull request #7 from JornVernee/Additional_Review_Comments >> >> Additional review comments >> - Revert System.java changes >> - Set copyright year for added files to 2020 >> - Check result of AttachCurrentThread >> - Sort includes alphabetically >> - Relax ret_addr_offset() assert >> - Extra space after if >> - remove excessive asserts in ProgrammableInvoker::invoke_native >> - Remove os::is_MP() check >> - remove blank line in thread.hpp > > I made a pass over hotspot code. Overall, it looks good. Some comments follow. I've just merged against master - which now contains the foreign memory API changes that this JEP depends on. I believe reviewing the changes should now be easier, as only the relevant changes should be presented in the "File Changed" tab. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From valeriep at openjdk.java.net Thu Nov 12 20:20:06 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Thu, 12 Nov 2020 20:20:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Mon, 2 Nov 2020 22:30:45 GMT, Anthony Scarpino wrote: >>> * It was my expectation that checkOutputCapacity() is making sure all the inOfs ==<> outOfs are going to work. Does that not catch all cases? >> checkOutputCapacity() as the name has, only changes that the output buffer is large enough. >> >>> * outWithPadding" is excessive because it doubles the allocation for every operation followed by a copy to the original buffer, even if the original buffer was adequate. I'm ok with doing the extra alloc & copy in certain situations, but not everytime. Can you be more specific what things may fail that we don't already check for in the regression tests? >> >> For example, >> 1) various input/output offset combinations, e.g. inOfs <,=,> outOfs, >> 2) Given a output buffer of 200-byte and outOfs == 0, assuming the returned decrypted data length is 160 bytes, the bytes from index 160 and onward should not be overwritten. GCM has no padding, so you may not notice any difference if this is what you are testing. This is generic CipherCore code and changes impact all ciphers. > > checkOutputCapacity: Yes.. The method includes the offsets for the output buffer, which I believe would verify that the output area in the buffer with offsets is large enough. > > outWithPadding: I understand the situation and I am assuming there are tests that cover this case. Given it's a generic situation. Have you tested the outWithPadding situation? Given that the existing impl only write out the final result, I don't think you can assume that existing tests cover it. I have wrote a simple test to check it if you have not done so, can you try it out to be sure? import java.io.PrintStream; import java.util.*; import java.security.*; import java.security.spec.*; import javax.crypto.*; import javax.crypto.spec.*; public class TestDoFinal { private static String ALGO = "AES"; private static int BLK_SIZE = 16; public static void main(String args[]) throws Exception { byte[] in = new byte[32]; Arrays.fill(in, (byte)8); KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE"); SecretKey skey = kg.generateKey(); Cipher ci = Cipher.getInstance(ALGO + "/CBC/PKCS5Padding", "SunJCE"); ci.init(Cipher.ENCRYPT_MODE, skey); int inLen = in.length - BLK_SIZE; byte[] out = ci.doFinal(in, 0, inLen); System.out.println("=> enc " + inLen + " bytes, ret " + (out == null? "null":(out.length + " byte"))); AlgorithmParameters param = ci.getParameters(); ci.init(Cipher.DECRYPT_MODE, skey, param); int rLen = ci.doFinal(out, 0, out.length, in); System.out.println("=> dec " + out.length + " bytes, ret " + rLen + " byte"); // check if more than rLen bytes are written into 'in' for (int j = rLen; j < in.length; j++) { if (in[j] != (byte)8) { throw new Exception("Value check failed at index " + j); } } System.out.println("Test Passed"); } } ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From jnimeh at openjdk.java.net Fri Nov 13 05:03:07 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Fri, 13 Nov 2020 05:03:07 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm Message-ID: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Hello all, This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. ------------- Commit messages: - Fix cut/paste error with ECDH-RSA key exchange - Merge - Initial EdDSA/TLS solution Changes: https://git.openjdk.java.net/jdk/pull/1197/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8166596 Stats: 842 lines in 9 files changed: 783 ins; 18 del; 41 mod Patch: https://git.openjdk.java.net/jdk/pull/1197.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1197/head:pull/1197 PR: https://git.openjdk.java.net/jdk/pull/1197 From mcimadamore at openjdk.java.net Fri Nov 13 11:38:24 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Fri, 13 Nov 2020 11:38:24 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v21] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with three additional commits since the last revision: - Fix crashes on aarch64 due to lack of intrinsics support - Fix high arity test for aarch64 - Fix build failure with disabled precompiled headers ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/e3d62ee7..15ab3647 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=20 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=19-20 Stats: 57 lines in 7 files changed: 52 ins; 0 del; 5 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Fri Nov 13 11:44:17 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Fri, 13 Nov 2020 11:44:17 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v22] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 83 commits: - Merge branch 'master' into 8254231_linker - Fix crashes on aarch64 due to lack of intrinsics support - Fix high arity test for aarch64 - Fix build failure with disabled precompiled headers - Fix whitespaces - Merge branch 'master' into 8254231_linker - Merge pull request #7 from JornVernee/Additional_Review_Comments Additional review comments - Revert System.java changes - Set copyright year for added files to 2020 - Check result of AttachCurrentThread - ... and 73 more: https://git.openjdk.java.net/jdk/compare/5973e91c...9b7cd259 ------------- Changes: https://git.openjdk.java.net/jdk/pull/634/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=21 Stats: 67506 lines in 214 files changed: 67329 ins; 79 del; 98 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From coffeys at openjdk.java.net Fri Nov 13 14:22:06 2020 From: coffeys at openjdk.java.net (Sean Coffey) Date: Fri, 13 Nov 2020 14:22:06 GMT Subject: RFR: 8253368: TLS connection always receives close_notify exception Message-ID: removing the "closing inbound before receiving peer's close_notify" exception that can be seen with TLS stack if calling close on inbound. After reading the relevant parts of the TLS v1.2/v1.3 RFCs, I believe the local end point doesn't have to wait for close_notify alert from remote end. ------------- Commit messages: - 8253368: TLS connection always receives close_notify exception Changes: https://git.openjdk.java.net/jdk/pull/1205/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1205&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8253368 Stats: 25 lines in 2 files changed: 12 ins; 10 del; 3 mod Patch: https://git.openjdk.java.net/jdk/pull/1205.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1205/head:pull/1205 PR: https://git.openjdk.java.net/jdk/pull/1205 From mcimadamore at openjdk.java.net Fri Nov 13 17:06:41 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Fri, 13 Nov 2020 17:06:41 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v23] In-Reply-To: References: Message-ID: <7igMkBiVz8heDwoSy6l7jyEr37zVgg6EIA7vNQrAFzA=.e7b3930b-e800-4426-a844-acffd744b64e@github.com> > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with six additional commits since the last revision: - Merge pull request #8 from JornVernee/Vlad_Comments Address More Review comments - - Don't print anything in nmehtod debug output for native invoker if there are none. - Use memcpy to copy native stubs to nmethod data - Simplify print code - Merge branch '8254231_linker' into Vlad_Comments - Address Vlad's review comments - Add ResourceMark to ProgrammableUpcallHandler constructor ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/9b7cd259..739c7925 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=22 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=21-22 Stats: 264 lines in 29 files changed: 72 ins; 112 del; 80 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From david.lloyd at redhat.com Fri Nov 13 17:11:30 2020 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 13 Nov 2020 11:11:30 -0600 Subject: RFR: 8253368: TLS connection always receives close_notify exception In-Reply-To: References: Message-ID: How would a truncation attack be avoided in this case? On Fri, Nov 13, 2020 at 8:23 AM Sean Coffey wrote: > > removing the "closing inbound before receiving peer's close_notify" exception that can be seen with TLS stack if calling close on inbound. After reading the relevant parts of the TLS v1.2/v1.3 RFCs, I believe the local end point doesn't have to wait for close_notify alert from remote end. > > ------------- > > Commit messages: > - 8253368: TLS connection always receives close_notify exception > > Changes: https://git.openjdk.java.net/jdk/pull/1205/files > Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1205&range=00 > Issue: https://bugs.openjdk.java.net/browse/JDK-8253368 > Stats: 25 lines in 2 files changed: 12 ins; 10 del; 3 mod > Patch: https://git.openjdk.java.net/jdk/pull/1205.diff > Fetch: git fetch https://git.openjdk.java.net/jdk pull/1205/head:pull/1205 > > PR: https://git.openjdk.java.net/jdk/pull/1205 > -- - DML ? he/him From weijun at openjdk.java.net Fri Nov 13 17:28:25 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 13 Nov 2020 17:28:25 GMT Subject: RFR: 8255255: Update Apache Santuario (XML Signature) to version 2.2.0 Message-ID: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> This is a multi-commits PR that upgrades xmldsig to be equivalent to Santuario 2.2.0. The first step is an auto-import. The JDK implementation is removed first and Santuario code are imported. Some unrelated files (Ex: encryption) are removed, and package names are renamed to be internal. There are also some bulk changes on company name, comment style, and white spaces. Next steps are patches applied by JDK. Some are old patches before the last import. Some are new. Several tests need to be updated because of internal method signature changes. The "Support RSA-PSS with parameters" commit introduces a new public API and would need a CSR. The last patch is one we just fixed several days ago. ------------- Commit messages: - Reapply 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() - Support RSA-PSS with parameters - Fix test failures - Supporting named RSASSA-PSS without parameters - Reapply 8008744: Rework part of fix for JDK-6741606 - Reapply 8151893: Add security property to configure XML Signature secure validation mode - Reapply Reapply 8042967: Add variant of DSA Signature algorithms that do not ASN.1 encode the signature bytes - Reapply 8038913: Bolster XML support (Init.java part) - Various warnings, the version, and abnormal copyright lines - Remove lines related to XML encryption - ... and 2 more: https://git.openjdk.java.net/jdk/compare/e8b75b13...ccb0caf3 Changes: https://git.openjdk.java.net/jdk/pull/1206/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1206&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8255255 Stats: 8044 lines in 188 files changed: 2705 ins; 3934 del; 1405 mod Patch: https://git.openjdk.java.net/jdk/pull/1206.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1206/head:pull/1206 PR: https://git.openjdk.java.net/jdk/pull/1206 From clanger at openjdk.java.net Fri Nov 13 17:31:59 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Fri, 13 Nov 2020 17:31:59 GMT Subject: Integrated: 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest In-Reply-To: References: Message-ID: On Wed, 11 Nov 2020 14:36:07 GMT, Christoph Langer wrote: > Working on 11u backports of JDK-8218021 and JDK-8250968, I found some minor points for improvement in tests > test/jdk/sun/security/tools/jarsigner/PosixPermissionsTest.java and > test/jdk/sun/security/tools/jarsigner/SymLinkTest.java > > The details > > PosixPermissionsTest: > - it can run on any system, no matter if the default filesystem supports Posix or not since Posix support is only required for the zipfs which is always true. > - improve some comments for the test flow > > SymLinkTest: > - make output of createByteArray prettier > - improve inline comments to ease understanding > - add an option to main for generating ZIPBYTES > - use "Files.write(Path.of(ZIPFILENAME), ZIPBYTES)" for creating the test zipfile This pull request has now been integrated. Changeset: 1e9a432d Author: Christoph Langer URL: https://git.openjdk.java.net/jdk/commit/1e9a432d Stats: 91 lines in 2 files changed: 34 ins; 7 del; 50 mod 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest Reviewed-by: mbaesken ------------- PR: https://git.openjdk.java.net/jdk/pull/1166 From coffeys at openjdk.java.net Fri Nov 13 17:45:02 2020 From: coffeys at openjdk.java.net (Sean Coffey) Date: Fri, 13 Nov 2020 17:45:02 GMT Subject: RFR: 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 06:44:27 GMT, Matthias Baesken wrote: >> Marked as reviewed by mbaesken (Reviewer). > > Looks good to me ! Meant to comment earlier. Thanks for cleaning this one up! ------------- PR: https://git.openjdk.java.net/jdk/pull/1166 From valeriep at openjdk.java.net Fri Nov 13 20:17:06 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 20:17:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 518: > 516: ArrayUtil.nullAndBoundsCheck(out, outOfs, inLen); > 517: byte[] block = new byte[blockSize]; > 518: int inLenUsed = constructBlock(ibuffer.toByteArray(), in, block); constructBlock takes 'in' but not 'inOfs'? Wouldn't the data be taken from the wrong index? No test catches this, strange? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 13 20:17:07 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 20:17:07 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 20:11:45 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: >> >> Code review comment update >> Major change to test to detect corruption with incremental buffers test > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 518: > >> 516: ArrayUtil.nullAndBoundsCheck(out, outOfs, inLen); >> 517: byte[] block = new byte[blockSize]; >> 518: int inLenUsed = constructBlock(ibuffer.toByteArray(), in, block); > > constructBlock takes 'in' but not 'inOfs'? Wouldn't the data be taken from the wrong index? No test catches this, strange? The assumption of this whole block here seems to be that ibuffer would not contain more than a block of buffered data? If that's the case, maybe we can just use 'ibuffer' instead of allocating a local 'block' and copy the data into it every time? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 13 20:51:04 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 20:51:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 540: > 538: // remainder offset is based on original buffer length > 539: ibuffer.write(in, inOfs + inLen, remainder); > 540: } I wonder if this can be moved down for better readability, i.e. process data in multiple of blocks, and store the remaining into 'ibuffer'? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 13 20:57:05 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 20:57:05 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 507: > 505: processAAD(); > 506: // 'len' stores the length to use with buffer 'in'. > 507: // 'inLen' stores the length returned by the method. line 551 has "return len;" which seems conflicting with these two-line comments here? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 13 21:00:06 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 21:00:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 563: > 561: } else { > 562: System.arraycopy(buffer, 0, block, 0, buflen); > 563: System.arraycopy(in, buflen, block, buflen, Use 'bufLen' as the offset for 'in' looks incorrect? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From sean.coffey at oracle.com Fri Nov 13 21:01:03 2020 From: sean.coffey at oracle.com (=?UTF-8?Q?Se=c3=a1n_Coffey?=) Date: Fri, 13 Nov 2020 21:01:03 +0000 Subject: RFR: 8253368: TLS connection always receives close_notify exception In-Reply-To: References: Message-ID: <3b1dd501-f6c0-13d9-9e5b-13732e06c385@oracle.com> Open to discussion on that. It's also highlighted in the TLSv1.3 RFC. The TLS spec doesn't require a fatal alert to be issued when closing inbound without receiving the peer's close_notify. I've seen a handful of applications making JDK upgrades which are seeing regression as a result of this new JDK check (like the one described in this bug). If we're to keep the check in the JDK, should we restrict it to the v1.3 protocol or should we implement it based on a system property perhaps ? regards, Sean. On 13/11/2020 17:11, David Lloyd wrote: > How would a truncation attack be avoided in this case? > > On Fri, Nov 13, 2020 at 8:23 AM Sean Coffey wrote: >> removing the "closing inbound before receiving peer's close_notify" exception that can be seen with TLS stack if calling close on inbound. After reading the relevant parts of the TLS v1.2/v1.3 RFCs, I believe the local end point doesn't have to wait for close_notify alert from remote end. >> >> ------------- >> >> Commit messages: >> - 8253368: TLS connection always receives close_notify exception >> >> Changes: https://git.openjdk.java.net/jdk/pull/1205/files >> Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1205&range=00 >> Issue: https://bugs.openjdk.java.net/browse/JDK-8253368 >> Stats: 25 lines in 2 files changed: 12 ins; 10 del; 3 mod >> Patch: https://git.openjdk.java.net/jdk/pull/1205.diff >> Fetch: git fetch https://git.openjdk.java.net/jdk pull/1205/head:pull/1205 >> >> PR: https://git.openjdk.java.net/jdk/pull/1205 >> > From valeriep at openjdk.java.net Fri Nov 13 21:04:05 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 21:04:05 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 560: > 558: System.arraycopy(buffer, 0, block, 0, blockSize); > 559: buflen -= block.length; > 560: return 0; Will bufLen > blockSize? Judging from the context of this method, buffer.length should always <= blockSize and never be larger? If bufLen == blockSize, perhaps we can just use buffer directly and no need to copy. src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 559: > 557: if (buflen >= blockSize) { > 558: System.arraycopy(buffer, 0, block, 0, blockSize); > 559: buflen -= block.length; bufLen isn't used, why bother updating its value? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From weijun at openjdk.java.net Fri Nov 13 21:21:02 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 13 Nov 2020 21:21:02 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec Message-ID: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> Without this method, `PSSParameterSpec::toString` shows something like: MD: SHA-256 MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 SaltLength: 32 TrailerField: 1 This is ugly. Noreg-trivial. ------------- Commit messages: - 8256363: Define toString() for MGF1ParameterSpec Changes: https://git.openjdk.java.net/jdk/pull/1208/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1208&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256363 Stats: 5 lines in 1 file changed: 5 ins; 0 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/1208.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1208/head:pull/1208 PR: https://git.openjdk.java.net/jdk/pull/1208 From weijun at openjdk.java.net Fri Nov 13 21:21:03 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 13 Nov 2020 21:21:03 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec In-Reply-To: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> Message-ID: On Fri, 13 Nov 2020 21:13:54 GMT, Weijun Wang wrote: > Without this method, `PSSParameterSpec::toString` shows something like: > MD: SHA-256 > MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 > SaltLength: 32 > TrailerField: 1 > This is ugly. > > Noreg-trivial. Do you want me to consolidate `PSSParameterSpec::toString` into one line? Multi-line toString is usually not very friendly to debug output (esp for grep). ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From david.lloyd at redhat.com Fri Nov 13 21:23:16 2020 From: david.lloyd at redhat.com (David Lloyd) Date: Fri, 13 Nov 2020 15:23:16 -0600 Subject: RFR: 8253368: TLS connection always receives close_notify exception In-Reply-To: <3b1dd501-f6c0-13d9-9e5b-13732e06c385@oracle.com> References: <3b1dd501-f6c0-13d9-9e5b-13732e06c385@oracle.com> Message-ID: Thinking about this some more, I suppose I tend to interpret the shutdownInput() API as indicating that the caller doesn't really care about any further data being received on the socket. I expect that a truncation attack would only be significant if the socket EOF was received before close_notify while the caller is trying to read data from the socket. So in that light the change is probably OK (since it only exists when explicitly shutting down the input) from the perspective that I was thinking of. Whether it has any protocol-level implications I don't know and won't comment on. That said, maybe shutdownInput(boolean) should be collapsed into shutdownInput() since the parameter is no longer used? On Fri, Nov 13, 2020 at 3:01 PM Se?n Coffey wrote: > > Open to discussion on that. It's also highlighted in the TLSv1.3 RFC. > > The TLS spec doesn't require a fatal alert to be issued when closing > inbound without receiving the peer's close_notify. I've seen a handful > of applications making JDK upgrades which are seeing regression as a > result of this new JDK check (like the one described in this bug). If > we're to keep the check in the JDK, should we restrict it to the v1.3 > protocol or should we implement it based on a system property perhaps ? > > regards, > Sean. > > On 13/11/2020 17:11, David Lloyd wrote: > > How would a truncation attack be avoided in this case? > > > > On Fri, Nov 13, 2020 at 8:23 AM Sean Coffey wrote: > >> removing the "closing inbound before receiving peer's close_notify" exception that can be seen with TLS stack if calling close on inbound. After reading the relevant parts of the TLS v1.2/v1.3 RFCs, I believe the local end point doesn't have to wait for close_notify alert from remote end. > >> > >> ------------- > >> > >> Commit messages: > >> - 8253368: TLS connection always receives close_notify exception > >> > >> Changes: https://git.openjdk.java.net/jdk/pull/1205/files > >> Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1205&range=00 > >> Issue: https://bugs.openjdk.java.net/browse/JDK-8253368 > >> Stats: 25 lines in 2 files changed: 12 ins; 10 del; 3 mod > >> Patch: https://git.openjdk.java.net/jdk/pull/1205.diff > >> Fetch: git fetch https://git.openjdk.java.net/jdk pull/1205/head:pull/1205 > >> > >> PR: https://git.openjdk.java.net/jdk/pull/1205 > >> > > > -- - DML ? he/him From weijun at openjdk.java.net Fri Nov 13 22:05:31 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 13 Nov 2020 22:05:31 GMT Subject: RFR: 8255255: Update Apache Santuario (XML Signature) to version 2.2.0 [v2] In-Reply-To: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> References: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> Message-ID: <6mjKEZHZfj4PWQqtpMPGTGeotuxQ76KgxP5kgFVt1NI=.64f5afd1-a67b-40a5-958e-290a22853545@github.com> > This is a multi-commits PR that upgrades xmldsig to be equivalent to Santuario 2.2.0. > > The first step is an auto-import. The JDK implementation is removed first and Santuario code are imported. Some unrelated files (Ex: encryption) are removed, and package names are renamed to be internal. There are also some bulk changes on company name, comment style, and white spaces. > > Next steps are patches applied by JDK. Some are old patches before the last import. Some are new. > > Several tests need to be updated because of internal method signature changes. > > The "Support RSA-PSS with parameters" commit introduces a new public API and would need a CSR. > > The last patch is one we just fixed several days ago. Weijun Wang has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains two new commits since the last revision: - Support RSA-PSS with parameters - Reapply 8255559: Leak File Descriptors Because of ResolverLocalFilesystem#engineResolveURI() ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1206/files - new: https://git.openjdk.java.net/jdk/pull/1206/files/ccb0caf3..73c73381 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1206&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1206&range=00-01 Stats: 141 lines in 3 files changed: 40 ins; 55 del; 46 mod Patch: https://git.openjdk.java.net/jdk/pull/1206.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1206/head:pull/1206 PR: https://git.openjdk.java.net/jdk/pull/1206 From weijun at openjdk.java.net Fri Nov 13 22:05:32 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 13 Nov 2020 22:05:32 GMT Subject: RFR: 8255255: Update Apache Santuario (XML Signature) to version 2.2.0 In-Reply-To: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> References: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> Message-ID: On Fri, 13 Nov 2020 17:22:10 GMT, Weijun Wang wrote: > This is a multi-commits PR that upgrades xmldsig to be equivalent to Santuario 2.2.0. > > The first step is an auto-import. The JDK implementation is removed first and Santuario code are imported. Some unrelated files (Ex: encryption) are removed, and package names are renamed to be internal. There are also some bulk changes on company name, comment style, and white spaces. > > Next steps are patches applied by JDK. Some are old patches before the last import. Some are new. > > Several tests need to be updated because of internal method signature changes. > > The "Support RSA-PSS with parameters" commit introduces a new public API and would need a CSR. > > The last patch is one we just fixed several days ago. The "Support RSA-PSS with parameters" commit is rewritten. Now a `PSSParameterSpec` object is encapsulated inside a `RSAPSSParameterSpec`. Note: https://tools.ietf.org/html/rfc6931#section-2.3.9 define the algorithm name as RSASSA-PSS with URI fragment `#rsa-pss` (no SSA). So in comments I always use the long name but the `SignatureMethod` constant is named `RSA_PSS`. Hopefully this is fine. ------------- PR: https://git.openjdk.java.net/jdk/pull/1206 From valeriep at openjdk.java.net Fri Nov 13 22:28:05 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 22:28:05 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 777: > 775: if ((src.remaining() + ((ibuffer != null) ? ibuffer.size() : 0) - > 776: tagLenBytes) > dst.remaining()) { > 777: throw new RuntimeException("output buffer too small"); Shouldn't this be ShortBufferException instead of RuntimeException? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Fri Nov 13 22:46:06 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Fri, 13 Nov 2020 22:46:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 20:13:42 GMT, Valerie Peng wrote: >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 518: >> >>> 516: ArrayUtil.nullAndBoundsCheck(out, outOfs, inLen); >>> 517: byte[] block = new byte[blockSize]; >>> 518: int inLenUsed = constructBlock(ibuffer.toByteArray(), in, block); >> >> constructBlock takes 'in' but not 'inOfs'? Wouldn't the data be taken from the wrong index? No test catches this, strange? > > The assumption of this whole block here seems to be that ibuffer would not contain more than a block of buffered data? If that's the case, maybe we can just use 'ibuffer' instead of allocating a local 'block' and copy the data into it every time? This is a very seldom used code path, There was only one existing test that accesses this code and it has not offset. constructBlock() is a generic method. There should be no case where ibuffer is >= blocksize during this method. For encryption the two encrypt() only put code in ibuffer. This method is for normal update() operations. The other encrypt is for any of the CipherCore internal buffer needs sent to GCM before doing the doFinal. At that point, ibuffer can be >= blocksize and doFinal will handle it. Some of this complication will go away with phase 2 of separating GCM from CipherCore ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Fri Nov 13 22:50:03 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Fri, 13 Nov 2020 22:50:03 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 20:54:15 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: >> >> Code review comment update >> Major change to test to detect corruption with incremental buffers test > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 507: > >> 505: processAAD(); >> 506: // 'len' stores the length to use with buffer 'in'. >> 507: // 'inLen' stores the length returned by the method. > > line 551 has "return len;" which seems conflicting with these two-line comments here? The comment is backwards. I wrote the comment before I decided to switch the meaning of the variables and never updated the comment ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 13 22:50:04 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 13 Nov 2020 22:50:04 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 16:34:30 GMT, Anthony Scarpino wrote: >> 8253821: Improve ByteBuffer performance with GCM > > Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: > > Code review comment update > Major change to test to detect corruption with incremental buffers test src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 822: > 820: if (len > dst.remaining()) { > 821: throw new ShortBufferException("Output buffer too small"); > 822: } How is this different from the check at line 775-778 at the beginning of this method? src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 818: > 816: // do this check here can also catch the potential integer overflow > 817: // scenario for the subsequent output buffer capacity check. > 818: checkDataLength(0, len); Perhaps this can be moved up to the beginning of this method just like the dst size check? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Sat Nov 14 00:25:06 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Sat, 14 Nov 2020 00:25:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: <1yXDpkbLCLryiBJhKlCNmFjKayV3KAud0TchLAFz-J0=.e07aabb5-a32d-4bdf-9b39-6ff9f14279d9@github.com> On Fri, 13 Nov 2020 20:47:53 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: >> >> Code review comment update >> Major change to test to detect corruption with incremental buffers test > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 540: > >> 538: // remainder offset is based on original buffer length >> 539: ibuffer.write(in, inOfs + inLen, remainder); >> 540: } > > I wonder if this can be moved down for better readability, i.e. process data in multiple of blocks, and store the remaining into 'ibuffer'? I tried to, but I don't like how the variable line up doing the remainder afterwards. I put some hopefully better comments above each section > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 563: > >> 561: } else { >> 562: System.arraycopy(buffer, 0, block, 0, buflen); >> 563: System.arraycopy(in, buflen, block, buflen, > > Use 'bufLen' as the offset for 'in' looks incorrect? Yes, it should be in's offset ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Sat Nov 14 00:36:06 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Sat, 14 Nov 2020 00:36:06 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 22:25:13 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: >> >> Code review comment update >> Major change to test to detect corruption with incremental buffers test > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 777: > >> 775: if ((src.remaining() + ((ibuffer != null) ? ibuffer.size() : 0) - >> 776: tagLenBytes) > dst.remaining()) { >> 777: throw new RuntimeException("output buffer too small"); > > Shouldn't this be ShortBufferException instead of RuntimeException? I thought so too, but that isn't what GCTR returns. All the GCTR checks are RuntimeExceptions. This check was original inside of GCTR, but I had to bring it out because of the ibuffer lengths. I don't mind changing, it's just a strange inconsistency. > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 822: > >> 820: if (len > dst.remaining()) { >> 821: throw new ShortBufferException("Output buffer too small"); >> 822: } > > How is this different from the check at line 775-778 at the beginning of this method? Ah.. good.. I'll remove the one above from GCTR as I liked this check better and it protects the GCTR update () > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 818: > >> 816: // do this check here can also catch the potential integer overflow >> 817: // scenario for the subsequent output buffer capacity check. >> 818: checkDataLength(0, len); > > Perhaps this can be moved up to the beginning of this method just like the dst size check? You don't know what 'len', which includes ibuffer data, until this point in the code. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From dongbo at openjdk.java.net Sat Nov 14 06:28:05 2020 From: dongbo at openjdk.java.net (Dong Bo) Date: Sat, 14 Nov 2020 06:28:05 GMT Subject: RFR: 8256318: AArch64: Add support for floating-point absolute difference Message-ID: This supports for floating-point absolute difference instructions, i.e. FABD scalar/vector. Verified with linux-aarch64-server-release, tier1-3. Added a JMH micro `test/micro/org/openjdk/bench/vm/compiler/FloatingScalarVectorAbsDiff.java` for performance test. The FABD (scalar), the performance tests handle registers directly, the average latency reduces to almost half (~57%) of the original. For FABD (vector), we restrict the data size (~24KB) to be less than L1 data cache size (32KB), so that the memory access can hit in L1, and witness 14.2% (float) and 21.2% (double) improvements. The JMH results on Kunpeng916: Benchmark (count) (seed) Mode Cnt Score Error Units # before, fsub+fabs FloatingScalarVectorAbsDiff.testScalarAbsDiffDouble 1024 316731 avgt 10 6038.333 ? 3.889 ns/op FloatingScalarVectorAbsDiff.testScalarAbsDiffFloat 1024 316731 avgt 10 6005.125 ? 3.025 ns/op FloatingScalarVectorAbsDiff.testVectorAbsDiffDouble 1024 316731 avgt 10 950.340 ? 9.398 ns/op FloatingScalarVectorAbsDiff.testVectorAbsDiffFloat 1024 316731 avgt 10 454.350 ? 1.798 ns/op # after, fabd FloatingScalarVectorAbsDiff.testScalarAbsDiffDouble 1024 316731 avgt 10 3483.801 ? 1.763 ns/op FloatingScalarVectorAbsDiff.testScalarAbsDiffFloat 1024 316731 avgt 10 3442.412 ? 1.866 ns/op FloatingScalarVectorAbsDiff.testVectorAbsDiffDouble 1024 316731 avgt 10 816.301 ? 4.454 ns/op FloatingScalarVectorAbsDiff.testVectorAbsDiffFloat 1024 316731 avgt 10 354.710 ? 1.001 ns/op ------------- Commit messages: - 8256318: AArch64: Add support for floating-point absolute difference Changes: https://git.openjdk.java.net/jdk/pull/1215/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1215&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256318 Stats: 209 lines in 20 files changed: 176 ins; 0 del; 33 mod Patch: https://git.openjdk.java.net/jdk/pull/1215.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1215/head:pull/1215 PR: https://git.openjdk.java.net/jdk/pull/1215 From clanger at openjdk.java.net Sat Nov 14 14:08:53 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Sat, 14 Nov 2020 14:08:53 GMT Subject: RFR: 8256202: Some tweaks for jarsigner tests PosixPermissionsTest and SymLinkTest In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 17:40:54 GMT, Sean Coffey wrote: > Meant to comment earlier. Thanks for cleaning this one up! Thanks :) Glad you like it. ------------- PR: https://git.openjdk.java.net/jdk/pull/1166 From coffeys at openjdk.java.net Mon Nov 16 08:17:53 2020 From: coffeys at openjdk.java.net (Sean Coffey) Date: Mon, 16 Nov 2020 08:17:53 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> Message-ID: On Fri, 13 Nov 2020 21:18:30 GMT, Weijun Wang wrote: >> Without this method, `PSSParameterSpec::toString` shows something like: >> MD: SHA-256 >> MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 >> SaltLength: 32 >> TrailerField: 1 >> This is ugly. >> >> Noreg-trivial. > > Do you want me to consolidate `PSSParameterSpec::toString` into one line? Multi-line toString is usually not very friendly to debug output (esp for grep). tidying PSSParameterSpec::toString into 1 line would be useful. thanks! ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mcimadamore at openjdk.java.net Mon Nov 16 11:30:22 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 16 Nov 2020 11:30:22 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v24] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with two additional commits since the last revision: - Merge pull request #9 from JornVernee/Windows_Warnings Fix warnings on MSVC - Fix warnings on MSVC ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/739c7925..000f75d5 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=23 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=22-23 Stats: 3 lines in 1 file changed: 1 ins; 0 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Mon Nov 16 13:05:30 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 16 Nov 2020 13:05:30 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v25] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Fix signature mismatch on aarch64 ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/000f75d5..3999a188 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=24 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=23-24 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From weijun at openjdk.java.net Mon Nov 16 14:25:20 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 16 Nov 2020 14:25:20 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> Message-ID: <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> > Without this method, `PSSParameterSpec::toString` shows something like: > MD: SHA-256 > MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 > SaltLength: 32 > TrailerField: 1 > This is ugly. > > Noreg-trivial. Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: make PSSParameterSpec one line only in patch2: unchanged: ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1208/files - new: https://git.openjdk.java.net/jdk/pull/1208/files/a78ee87e..3b0a4c83 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1208&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1208&range=00-01 Stats: 5 lines in 1 file changed: 0 ins; 0 del; 5 mod Patch: https://git.openjdk.java.net/jdk/pull/1208.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1208/head:pull/1208 PR: https://git.openjdk.java.net/jdk/pull/1208 From coffeys at openjdk.java.net Mon Nov 16 14:46:11 2020 From: coffeys at openjdk.java.net (Sean Coffey) Date: Mon, 16 Nov 2020 14:46:11 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 14:25:20 GMT, Weijun Wang wrote: >> Without this method, `PSSParameterSpec::toString` shows something like: >> MD: SHA-256 >> MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 >> SaltLength: 32 >> TrailerField: 1 >> This is ugly. >> >> Noreg-trivial. > > Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: > > make PSSParameterSpec one line > > only in patch2: > unchanged: minor comment on spacing for MGF1 toString() src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java line 168: > 166: @Override > 167: public String toString() { > 168: return "MGF1:" + mdName; do you want to insert a space after ':' ? ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mullan at openjdk.java.net Mon Nov 16 16:14:09 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 16 Nov 2020 16:14:09 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 14:25:20 GMT, Weijun Wang wrote: >> Without this method, `PSSParameterSpec::toString` shows something like: >> MD: SHA-256 >> MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 >> SaltLength: 32 >> TrailerField: 1 >> This is ugly. >> >> Noreg-trivial. > > Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: > > make PSSParameterSpec one line > > only in patch2: > unchanged: src/java.base/share/classes/java/security/spec/PSSParameterSpec.java line 224: > 222: public String toString() { > 223: StringBuilder sb = new StringBuilder(); > 224: sb.append("MD: " + mdName + ", ") I would replace "MD" with "DigestAlgorithm" to be consistent with the names of the other fields. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mullan at openjdk.java.net Mon Nov 16 16:22:04 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 16 Nov 2020 16:22:04 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 14:25:20 GMT, Weijun Wang wrote: >> Without this method, `PSSParameterSpec::toString` shows something like: >> MD: SHA-256 >> MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 >> SaltLength: 32 >> TrailerField: 1 >> This is ugly. >> >> Noreg-trivial. > > Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: > > make PSSParameterSpec one line > > only in patch2: > unchanged: src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java line 168: > 166: @Override > 167: public String toString() { > 168: return "MGF1:" + mdName; I would replace "MGF1" or perhaps add "DigestAlgorithm" which is the name of the attribute. Is it necessary to print that this is an MGF1? PSSParameterSpec does not print that it is an RSASSA-PSS-params, and also prints "MGF", so it seems there would be some duplication. It almost seems like we should have some rules regarding how these parameters are printed out so everything is consistent. Or perhaps it makes sense to have brackets around the fields. Otherwise when you chain several toStrings together, it makes it more difficult to discern when one field ends and the next begins. Hmm. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mullan at openjdk.java.net Mon Nov 16 16:33:01 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 16 Nov 2020 16:33:01 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 14:43:26 GMT, Sean Coffey wrote: >> Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: >> >> make PSSParameterSpec one line >> >> only in patch2: >> unchanged: > > minor comment on spacing for MGF1 toString() > Do you want me to consolidate `PSSParameterSpec::toString` into one line? Multi-line toString is usually not very friendly to debug output (esp for grep). Good question. Readability is important though. I think it depends on the number of fields and we should try to use a consistent format if possible. Something like X509Certificate.toString would be very unfriendly if it returned a one-line String, or if the toString impls of different fields used different formatting. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mcimadamore at openjdk.java.net Mon Nov 16 16:45:31 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 16 Nov 2020 16:45:31 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v26] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Fix aarch64 test failure ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/3999a188..a836cc32 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=25 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=24-25 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From weijun at openjdk.java.net Mon Nov 16 18:10:12 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 16 Nov 2020 18:10:12 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 08:14:00 GMT, Sean Coffey wrote: >> Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: >> >> make PSSParameterSpec one line >> >> only in patch2: >> unchanged: > > src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java line 168: > >> 166: @Override >> 167: public String toString() { >> 168: return "MGF1:" + mdName; > > do you want to insert a space after ':' ? The current MGF part shows `MGF: MGF1:SHA-256`. An extra space would looks a little strange, and you don't know if the key is `MGF: MGF1` or ``MGF`. I'd rather keep the current output. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From weijun at openjdk.java.net Mon Nov 16 18:23:05 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 16 Nov 2020 18:23:05 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 16:19:16 GMT, Sean Mullan wrote: >> Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: >> >> make PSSParameterSpec one line >> >> only in patch2: >> unchanged: > > src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java line 168: > >> 166: @Override >> 167: public String toString() { >> 168: return "MGF1:" + mdName; > > I would replace "MGF1" or perhaps add "DigestAlgorithm" which is the name of the attribute. Is it necessary to print that this is an MGF1? PSSParameterSpec does not print that it is an RSASSA-PSS-params, and also prints "MGF", so it seems there would be some duplication. It almost seems like we should have some rules regarding how these parameters are printed out so everything is consistent. > > Or perhaps it makes sense to have brackets around the fields. Otherwise when you chain several toStrings together, it makes it more difficult to discern when one field ends and the next begins. Hmm. "MGF1" is only one kind of MGF and we might see "MGF2" in the future so it's worth printing out. Of course, `PSSParameterSpec` already has a `getMGFAlgorithm()` so the name can either be printed in the `toString` of the outer data type or the inner one. As for `DigestAlgorithm` I don't think it's necessary because it's the only field for MGF1 so there's no ambiguity. That said, we can try to provide some consistency here. If the types had been defined as records with static record MGF1Params(String messageDigest) {} static record PssParams(String messageDigest, String mgfAlgorithm, MGF1Params mgfParams, int saltLength, int trailerField) {} The automatically generated `toString` would output something like PssParams[messageDigest=SHA-1, mgfAlgorithm=MGF1, mgfParams=MGF1Params[messageDigest=SHA-1], saltLength=20, trailerField=1] It's a little verbose. Do you like this style? ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From valeriep at openjdk.java.net Mon Nov 16 18:40:06 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 16 Nov 2020 18:40:06 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 18:07:39 GMT, Weijun Wang wrote: >> src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java line 168: >> >>> 166: @Override >>> 167: public String toString() { >>> 168: return "MGF1:" + mdName; >> >> do you want to insert a space after ':' ? > > The current MGF part shows `MGF: MGF1:SHA-256`. An extra space would looks a little strange, and you don't know if the key is `MGF: MGF1` or ``MGF`. I'd rather keep the current output. How about just MGF: MGF1SHA-256 or MGF: MGF1 SHA-256? First combines into a single string, the second uses space instead of ":". Just a suggestion. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mcimadamore at openjdk.java.net Mon Nov 16 18:52:27 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 16 Nov 2020 18:52:27 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v27] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: Add `final` modifier on NativeLibraries.defaultLookup ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/634/files - new: https://git.openjdk.java.net/jdk/pull/634/files/a836cc32..a71d51a0 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=26 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=25-26 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From rhalade at openjdk.java.net Mon Nov 16 18:52:29 2020 From: rhalade at openjdk.java.net (Rajan Halade) Date: Mon, 16 Nov 2020 18:52:29 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v26] In-Reply-To: References: Message-ID: <_MAO7-ELT_n5RxduwWzN7gJ23wpv06mQZftEFwtNWYs=.579b699a-8424-4eac-9b30-b37607e1ba32@github.com> On Mon, 16 Nov 2020 16:45:31 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: > > Fix aarch64 test failure src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java line 387: > 385: } > 386: > 387: public static NativeLibrary defaultLibrary = new NativeLibraryImpl(Object.class, "", true, true) { This field can be final. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From valeriep at openjdk.java.net Mon Nov 16 19:16:17 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 16 Nov 2020 19:16:17 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Sat, 14 Nov 2020 00:29:41 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 777: >> >>> 775: if ((src.remaining() + ((ibuffer != null) ? ibuffer.size() : 0) - >>> 776: tagLenBytes) > dst.remaining()) { >>> 777: throw new RuntimeException("output buffer too small"); >> >> Shouldn't this be ShortBufferException instead of RuntimeException? > > I thought so too, but that isn't what GCTR returns. All the GCTR checks are RuntimeExceptions. This check was original inside of GCTR, but I had to bring it out because of the ibuffer lengths. I don't mind changing, it's just a strange inconsistency. GaloisCounterMode is the caller class of GCTR and this API is meant to throw ShortBufferException I think (based on the check at lines below at 820-822)... >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 540: >> >>> 538: // remainder offset is based on original buffer length >>> 539: ibuffer.write(in, inOfs + inLen, remainder); >>> 540: } >> >> I wonder if this can be moved down for better readability, i.e. process data in multiple of blocks, and store the remaining into 'ibuffer'? > > I tried to, but I don't like how the variable line up doing the remainder afterwards. I put some hopefully better comments above each section Ok. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 16 19:21:13 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 16 Nov 2020 19:21:13 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 22:43:17 GMT, Anthony Scarpino wrote: >> The assumption of this whole block here seems to be that ibuffer would not contain more than a block of buffered data? If that's the case, maybe we can just use 'ibuffer' instead of allocating a local 'block' and copy the data into it every time? > > This is a very seldom used code path, There was only one existing test that accesses this code and it has not offset. > > constructBlock() is a generic method. There should be no case where ibuffer is >= blocksize during this method. For encryption the two encrypt() only put code in ibuffer. This method is for normal update() operations. The other encrypt is for any of the CipherCore internal buffer needs sent to GCM before doing the doFinal. At that point, ibuffer can be >= blocksize and doFinal will handle it. Some of this complication will go away with phase 2 of separating GCM from CipherCore The current impl of constructBlock() seems to have code handling ibuffer >= blocksize scenario. Could you fix that and also pass the input offset into constructBlock() for this RFE? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Mon Nov 16 19:26:15 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 16 Nov 2020 19:26:15 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Sat, 14 Nov 2020 00:33:35 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 818: >> >>> 816: // do this check here can also catch the potential integer overflow >>> 817: // scenario for the subsequent output buffer capacity check. >>> 818: checkDataLength(0, len); >> >> Perhaps this can be moved up to the beginning of this method just like the dst size check? > > You don't know what 'len', which includes ibuffer data, until this point in the code. Well, didn't you already calcuate the 'len' value in the beginning of the copied-from-GCTR RuntimeException check? ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From mullan at openjdk.java.net Mon Nov 16 20:24:09 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 16 Nov 2020 20:24:09 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 Message-ID: This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 ------------- Commit messages: - 8202343: Disable TLS 1.0 and 1.1 - 8202343: Disable TLS 1.0 and 1.1 Changes: https://git.openjdk.java.net/jdk/pull/1235/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1235&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8202343 Stats: 393 lines in 20 files changed: 269 ins; 97 del; 27 mod Patch: https://git.openjdk.java.net/jdk/pull/1235.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1235/head:pull/1235 PR: https://git.openjdk.java.net/jdk/pull/1235 From weijun at openjdk.java.net Mon Nov 16 20:52:03 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 16 Nov 2020 20:52:03 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 18:37:13 GMT, Valerie Peng wrote: >> The current MGF part shows `MGF: MGF1:SHA-256`. An extra space would looks a little strange, and you don't know if the key is `MGF: MGF1` or `MGF`. I'd rather keep the current output. > > How about just MGF: MGF1SHA-256 or MGF: MGF1 SHA-256? > First combines into a single string, the second uses space instead of ":". Just a suggestion. I like the 2nd one better, but I'll see how Sean thinks about the verbose record-style toString. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From weijun at openjdk.java.net Mon Nov 16 21:16:06 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 16 Nov 2020 21:16:06 GMT Subject: Withdrawn: 8255255: Update Apache Santuario (XML Signature) to version 2.2.0 In-Reply-To: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> References: <9HSWW2iZvPdRsRM2V485qP8EEVfrr-HliiCLcBmo39M=.59e3740a-3c7e-4081-bbea-45ef41e102cd@github.com> Message-ID: <9OwWZsyRAm8buLTFjEfv30gHGiW-SwAl9w6fREJ6XbM=.ebd8ec85-d9f1-4c51-9657-2516ef762c86@github.com> On Fri, 13 Nov 2020 17:22:10 GMT, Weijun Wang wrote: > This is a multi-commits PR that upgrades xmldsig to be equivalent to Santuario 2.2.0. > > The first step is an auto-import. The JDK implementation is removed first and Santuario code are imported. Some unrelated files (Ex: encryption) are removed, and package names are renamed to be internal. There are also some bulk changes on company name, comment style, and white spaces. > > Next steps are patches applied by JDK. Some are old patches before the last import. Some are new. > > Several tests need to be updated because of internal method signature changes. > > The "Support RSA-PSS with parameters" commit introduces a new public API and would need a CSR. > > The last patch is one we just fixed several days ago. This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.java.net/jdk/pull/1206 From mullan at openjdk.java.net Mon Nov 16 22:07:14 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 16 Nov 2020 22:07:14 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 18:20:02 GMT, Weijun Wang wrote: >> src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java line 168: >> >>> 166: @Override >>> 167: public String toString() { >>> 168: return "MGF1:" + mdName; >> >> I would replace "MGF1" or perhaps add "DigestAlgorithm" which is the name of the attribute. Is it necessary to print that this is an MGF1? PSSParameterSpec does not print that it is an RSASSA-PSS-params, and also prints "MGF", so it seems there would be some duplication. It almost seems like we should have some rules regarding how these parameters are printed out so everything is consistent. >> >> Or perhaps it makes sense to have brackets around the fields. Otherwise when you chain several toStrings together, it makes it more difficult to discern when one field ends and the next begins. Hmm. > > "MGF1" is only one kind of MGF and we might see "MGF2" in the future so it's worth printing out. Of course, `PSSParameterSpec` already has a `getMGFAlgorithm()` so the name can either be printed in the `toString` of the outer data type or the inner one. > > As for `DigestAlgorithm` I don't think it's necessary because it's the only field for MGF1 so there's no ambiguity. > > That said, we can try to provide some consistency here. If the types had been defined as records with > static record MGF1Params(String messageDigest) {} > static record PssParams(String messageDigest, String mgfAlgorithm, > MGF1Params mgfParams, int saltLength, int trailerField) {} > The automatically generated `toString` would output something like > PssParams[messageDigest=SHA-1, mgfAlgorithm=MGF1, mgfParams=MGF1Params[messageDigest=SHA-1], saltLength=20, trailerField=1] > It's a little verbose. Do you like this style? I like the brackets surrounding the fields of each type. I think we should try to use brackets in the toString methods of security classes as there is often a deep hierarchy of objects and the brackets helps to see that. I also like seeing the actual type for non-primitives, and not an abbreviated form. As for the names of the fields, I'm ok with whatever seems most reasonable, the ASN.1 names, or the method or parameter names. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mullan at openjdk.java.net Mon Nov 16 22:07:16 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 16 Nov 2020 22:07:16 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: <26EFKHpCb-CvIPmIiKk1nr8f3mwvLAsa-Mth3H5sMns=.da498297-9353-478b-b4fb-52cfa673a242@github.com> On Mon, 16 Nov 2020 20:49:15 GMT, Weijun Wang wrote: >> How about just MGF: MGF1SHA-256 or MGF: MGF1 SHA-256? >> First combines into a single string, the second uses space instead of ":". Just a suggestion. > > I like the 2nd one better, but I'll see how Sean thinks about the verbose record-style toString. 99% of the time, it will probably be one of the MGF1ParameterSpec constants. For those, perhaps it would be nice to just use the constant: "MGF: MGF1ParameterSpec.SHA1" and for anything else, "MGF: MGF1ParameterSpec [digestAlgorithm: ...>". If this is too complicated, then I am ok with the above. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From xuelei at openjdk.java.net Mon Nov 16 22:09:03 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Mon, 16 Nov 2020 22:09:03 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 In-Reply-To: References: Message-ID: <92m0G84f8-unyiKaNXHvKB75uMFFw7HzJLhG6iNQqOM=.6d4351ca-299a-4299-842e-4c1eb7b1bade@github.com> On Mon, 16 Nov 2020 20:18:16 GMT, Sean Mullan wrote: > This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 > > The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java Marked as reviewed by xuelei (Reviewer). test/jdk/javax/net/ssl/sanity/ciphersuites/TLSCipherSuitesOrder.java line 76: > 74: if (protocol.equals("TLSv1") || protocol.equals("TLSv1.1")) { > 75: SecurityUtils.removeFromDisabledTlsAlgs(protocol); > 76: } There are several property updates in method other than the main() method. It should be fine as the constructor is private. It is safer to make the update in the main() method as the property is loaded one time only in JVM. test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java line 150: > 148: // Re-enable TLSv1 since test depends on it > 149: SecurityUtils.removeFromDisabledTlsAlgs("TLSv1"); > 150: I would like move this block to the main() method for safe, or have this method private. ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From mcimadamore at openjdk.java.net Tue Nov 17 11:15:13 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Tue, 17 Nov 2020 11:15:13 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v26] In-Reply-To: <_MAO7-ELT_n5RxduwWzN7gJ23wpv06mQZftEFwtNWYs=.579b699a-8424-4eac-9b30-b37607e1ba32@github.com> References: <_MAO7-ELT_n5RxduwWzN7gJ23wpv06mQZftEFwtNWYs=.579b699a-8424-4eac-9b30-b37607e1ba32@github.com> Message-ID: On Mon, 16 Nov 2020 18:44:55 GMT, Rajan Halade wrote: >> Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision: >> >> Fix aarch64 test failure > > src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java line 387: > >> 385: } >> 386: >> 387: public static NativeLibrary defaultLibrary = new NativeLibraryImpl(Object.class, "", true, true) { > > This field can be final. Thanks - I already made this change in the latest revision. ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From mcimadamore at openjdk.java.net Tue Nov 17 11:49:26 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Tue, 17 Nov 2020 11:49:26 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v28] In-Reply-To: References: Message-ID: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 95 commits: - Merge branch 'master' into 8254231_linker - Add `final` modifier on NativeLibraries.defaultLookup - Fix aarch64 test failure - Fix signature mismatch on aarch64 - Merge pull request #9 from JornVernee/Windows_Warnings Fix warnings on MSVC - Fix warnings on MSVC - Merge pull request #8 from JornVernee/Vlad_Comments Address More Review comments - - Don't print anything in nmehtod debug output for native invoker if there are none. - Use memcpy to copy native stubs to nmethod data - Simplify print code - Merge branch '8254231_linker' into Vlad_Comments - ... and 85 more: https://git.openjdk.java.net/jdk/compare/a7422ac2...40bd5df1 ------------- Changes: https://git.openjdk.java.net/jdk/pull/634/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=634&range=27 Stats: 67469 lines in 212 files changed: 67290 ins; 79 del; 100 mod Patch: https://git.openjdk.java.net/jdk/pull/634.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/634/head:pull/634 PR: https://git.openjdk.java.net/jdk/pull/634 From weijun at openjdk.java.net Tue Nov 17 15:31:05 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 17 Nov 2020 15:31:05 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v2] In-Reply-To: <26EFKHpCb-CvIPmIiKk1nr8f3mwvLAsa-Mth3H5sMns=.da498297-9353-478b-b4fb-52cfa673a242@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> <26EFKHpCb-CvIPmIiKk1nr8f3mwvLAsa-Mth3H5sMns=.da498297-9353-478b-b4fb-52cfa673a242@github.com> Message-ID: <82Frc3x6vG0KQafyl39sQZKTQiXAK4VQExhorpbubVk=.eb8c181b-12a1-45f9-9e92-64daa4438119@github.com> On Mon, 16 Nov 2020 22:04:21 GMT, Sean Mullan wrote: >> I like the 2nd one better, but I'll see how Sean thinks about the verbose record-style toString. > > 99% of the time, it will probably be one of the MGF1ParameterSpec constants. For those, perhaps it would be nice to just use the constant: "MGF: MGF1ParameterSpec.SHA1" and for anything else, "MGF: MGF1ParameterSpec [digestAlgorithm: ...>". If this is too complicated, then I am ok with the above. This is doable and probably will be fast if I just keep checking `if (this == MGF1ParameterSpec.SHA1) return "MGF1ParameterSpec.SHA1"` but the code will be quite long. There are 11 constants. Maybe if this class were an enumeration... ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mullan at openjdk.java.net Tue Nov 17 15:36:10 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Tue, 17 Nov 2020 15:36:10 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 In-Reply-To: <92m0G84f8-unyiKaNXHvKB75uMFFw7HzJLhG6iNQqOM=.6d4351ca-299a-4299-842e-4c1eb7b1bade@github.com> References: <92m0G84f8-unyiKaNXHvKB75uMFFw7HzJLhG6iNQqOM=.6d4351ca-299a-4299-842e-4c1eb7b1bade@github.com> Message-ID: <2ZsH9L1s1FuJUhbscVGE567KiQ7fcIU1F0SXa19Etvw=.346fea41-5c2e-4ecc-a36b-dc57959b1afa@github.com> On Mon, 16 Nov 2020 22:02:05 GMT, Xue-Lei Andrew Fan wrote: >> This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 >> >> The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java > > test/jdk/javax/net/ssl/sanity/ciphersuites/TLSCipherSuitesOrder.java line 76: > >> 74: if (protocol.equals("TLSv1") || protocol.equals("TLSv1.1")) { >> 75: SecurityUtils.removeFromDisabledTlsAlgs(protocol); >> 76: } > > There are several property updates in method other than the main() method. It should be fine as the constructor is private. It is safer to make the update in the main() method as the property is loaded one time only in JVM. I think it is safe to set the property in the constructor because the test always runs in its own VM using the jtreg `othervm` option and there are no methods called by main before the constructor that would cause the value of "jdk.tls.disabledAlgorithms" to be fetched and cached. Let me know if you think otherwise. > test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java line 150: > >> 148: // Re-enable TLSv1 since test depends on it >> 149: SecurityUtils.removeFromDisabledTlsAlgs("TLSv1"); >> 150: > > I would like move this block to the main() method for safe, or have this method private. Ok. ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From weijun at openjdk.java.net Tue Nov 17 15:37:18 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 17 Nov 2020 15:37:18 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v3] In-Reply-To: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> Message-ID: <3pbjCPvkbyoGC-c6gOFCUXD0nQxEp6qPswDrmqRn2dE=.b5f46930-ba57-4e2f-b8dd-439f8fbd8a6b@github.com> > Without this method, `PSSParameterSpec::toString` shows something like: > MD: SHA-256 > MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 > SaltLength: 32 > TrailerField: 1 > This is ugly. > > Noreg-trivial. Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: choose a record-style format ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1208/files - new: https://git.openjdk.java.net/jdk/pull/1208/files/3b0a4c83..a3ab69e5 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1208&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1208&range=01-02 Stats: 12 lines in 3 files changed: 1 ins; 2 del; 9 mod Patch: https://git.openjdk.java.net/jdk/pull/1208.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1208/head:pull/1208 PR: https://git.openjdk.java.net/jdk/pull/1208 From weijun at openjdk.java.net Tue Nov 17 15:37:19 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 17 Nov 2020 15:37:19 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v3] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Mon, 16 Nov 2020 16:30:04 GMT, Sean Mullan wrote: >> minor comment on spacing for MGF1 toString() > >> Do you want me to consolidate `PSSParameterSpec::toString` into one line? Multi-line toString is usually not very friendly to debug output (esp for grep). > > Good question. Readability is important though. I think it depends on the number of fields and we should try to use a consistent format if possible. Something like X509Certificate.toString would be very unfriendly if it returned a one-line String, or if the toString impls of different fields used different formatting. New commit and the output will look like: PSSParameterSpec[hashAlgorithm=SHA-256, maskGenAlgorithm=MGF1ParameterSpec[hashAlgorithm=SHA-256], saltLength=32, trailerField=1] I'm using the ASN.1 field names here. (Precisely the name in MGF1 is OAEP-PSSDigestAlgorithms but that's too long). ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From mullan at openjdk.java.net Tue Nov 17 17:55:19 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Tue, 17 Nov 2020 17:55:19 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 [v2] In-Reply-To: References: Message-ID: > This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 > > The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: More test changes. ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1235/files - new: https://git.openjdk.java.net/jdk/pull/1235/files/71d49643..4daf0154 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1235&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1235&range=00-01 Stats: 10 lines in 2 files changed: 7 ins; 3 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/1235.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1235/head:pull/1235 PR: https://git.openjdk.java.net/jdk/pull/1235 From xuelei at openjdk.java.net Tue Nov 17 18:12:11 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Tue, 17 Nov 2020 18:12:11 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 [v2] In-Reply-To: References: Message-ID: <2XlculjVWBb0MBJz5yVq5L5sx66NvhfT-wnu8X3We2o=.2b210036-54b2-40ea-9552-584752ade052@github.com> On Tue, 17 Nov 2020 17:55:19 GMT, Sean Mullan wrote: >> This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 >> >> The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java > > Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: > > More test changes. Marked as reviewed by xuelei (Reviewer). test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java line 95: > 93: > 94: private SSLEngine clientEngine; // client Engine > 95: private ByteBuffer clientOut; // write side of clientEngine Good to see cleanup like this. ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From dfuchs at openjdk.java.net Tue Nov 17 18:25:08 2020 From: dfuchs at openjdk.java.net (Daniel Fuchs) Date: Tue, 17 Nov 2020 18:25:08 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 [v2] In-Reply-To: References: Message-ID: <89g4aynrShZI5zOr7MFv1AwWeP7pvfkvKBByNsu3h_U=.d75c9513-9c98-4839-8f8d-c2a694fe144d@github.com> On Tue, 17 Nov 2020 17:55:19 GMT, Sean Mullan wrote: >> This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 >> >> The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java > > Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: > > More test changes. Marked as reviewed by dfuchs (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From dfuchs at openjdk.java.net Tue Nov 17 18:25:10 2020 From: dfuchs at openjdk.java.net (Daniel Fuchs) Date: Tue, 17 Nov 2020 18:25:10 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 [v2] In-Reply-To: <2XlculjVWBb0MBJz5yVq5L5sx66NvhfT-wnu8X3We2o=.2b210036-54b2-40ea-9552-584752ade052@github.com> References: <2XlculjVWBb0MBJz5yVq5L5sx66NvhfT-wnu8X3We2o=.2b210036-54b2-40ea-9552-584752ade052@github.com> Message-ID: On Tue, 17 Nov 2020 18:09:03 GMT, Xue-Lei Andrew Fan wrote: >> Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: >> >> More test changes. > > Marked as reviewed by xuelei (Reviewer). Hi Sean, The changes to the HttpClient test look good to me. best regards, -- daniel ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From xuelei at openjdk.java.net Tue Nov 17 19:11:07 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Tue, 17 Nov 2020 19:11:07 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 13 Nov 2020 04:57:12 GMT, Jamil Nimeh wrote: > Hello all, > This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 35: > 33: * SunJSSE does not support dynamic system properties, no way to re-use > 34: * system properties in samevm/agentvm mode. > 35: */ Leading white spaces could be removed. I may put this comment before the "@test" block to be consistent with other test cases. test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 74: > 72: > 73: public class TLSWithEdDSA extends SSLSocketTemplate { > 74: static final boolean DEBUG = false; I may not use this filed. The debug property could be specified in the "@run" tag if needed. test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 81: > 79: static final String DEF_ALL_EE = "EE_ECDSA_SECP256R1:EE_ECDSA_SECP384R1:" + > 80: "EE_ECDSA_SECP521R1:EE_RSA_2048:EE_EC_RSA_SECP256R1:" + > 81: "EE_DSA_2048:EE_DSA_1024:EE_ED25519:EE_ED448"; Why not use enum, array or collection directly? Which is easy to read, I think. test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 92: > 90: final SessionChecker serverChecker; > 91: final Class clientException; > 92: final Class serverException; If no problem, I may declare the class fields and inner classes as private for safe. test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 592: > 590: } > 591: > 592: private static void keyManagerTests(String keyStoreSpec, String keyType, Java method name is normally an action. What do you think if update to testKeyManager()? test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 583: > 581: serverParameters.put(ParamType.CERTALIAS, "EE_ED25519"); > 582: runtest(testFormat, isPeerEd25519, null, null, null); > 583: serverParameters.remove(ParamType.CERTALIAS); I did not get the idea here. Is there a special case in practice that use a similar key manger like the AliasKeyManager? ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From mullan at openjdk.java.net Tue Nov 17 19:39:06 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Tue, 17 Nov 2020 19:39:06 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v3] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Tue, 17 Nov 2020 15:34:37 GMT, Weijun Wang wrote: > New commit and the output will look like: > > ``` > PSSParameterSpec[hashAlgorithm=SHA-256, maskGenAlgorithm=MGF1ParameterSpec[hashAlgorithm=SHA-256], saltLength=32, trailerField=1] > ``` > > I'm using the ASN.1 field names here. (Precisely the name in MGF1 is OAEP-PSSDigestAlgorithms but that's too long). I like it. Looks good. ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From jnimeh at openjdk.java.net Tue Nov 17 19:43:06 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Tue, 17 Nov 2020 19:43:06 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 18:24:35 GMT, Xue-Lei Andrew Fan wrote: >> Hello all, >> This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. > > test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 35: > >> 33: * SunJSSE does not support dynamic system properties, no way to re-use >> 34: * system properties in samevm/agentvm mode. >> 35: */ > > Leading white spaces could be removed. I may put this comment before the "@test" block to be consistent with other test cases. No problem, I'll take care of that. > test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 74: > >> 72: >> 73: public class TLSWithEdDSA extends SSLSocketTemplate { >> 74: static final boolean DEBUG = false; > > I may not use this filed. The debug property could be specified in the "@run" tag if needed. No problem. Will change. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Tue Nov 17 19:47:05 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Tue, 17 Nov 2020 19:47:05 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 18:29:13 GMT, Xue-Lei Andrew Fan wrote: >> Hello all, >> This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. > > test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 81: > >> 79: static final String DEF_ALL_EE = "EE_ECDSA_SECP256R1:EE_ECDSA_SECP384R1:" + >> 80: "EE_ECDSA_SECP521R1:EE_RSA_2048:EE_EC_RSA_SECP256R1:" + >> 81: "EE_DSA_2048:EE_DSA_1024:EE_ED25519:EE_ED448"; > > Why not use enum, array or collection directly? Which is easy to read, I think. I don't think there's any reason why we could use a Collection for these. I'll try switching to that. > test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 592: > >> 590: } >> 591: >> 592: private static void keyManagerTests(String keyStoreSpec, String keyType, > > Java method name is normally an action. What do you think if update to testKeyManager()? Sure, easy enough to do. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Tue Nov 17 19:51:06 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Tue, 17 Nov 2020 19:51:06 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 19:07:33 GMT, Xue-Lei Andrew Fan wrote: >> Hello all, >> This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. > > test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 583: > >> 581: serverParameters.put(ParamType.CERTALIAS, "EE_ED25519"); >> 582: runtest(testFormat, isPeerEd25519, null, null, null); >> 583: serverParameters.remove(ParamType.CERTALIAS); > > I did not get the idea here. Is there a special case in practice that use a similar key manger like the AliasKeyManager? Right now, for TLS 1.0/1.1 EC certificates will be favored over EdDSA certificates in keystores that have valid certificates with both kinds of keys. There's nothing we can do about that because 1.0/1.1 has no signaling mechanism to indicate signature preference like 1.2+ has. Given that, I was thinking of ways to get around that restriction and one case I thought of was the Tomcat connector, which has options to specify a certificate for use by alias. I wanted to make sure that we could still do that for 1.0/1.1 and it wouldn't break so I cooked up this simple KeyManager and ran a basic connection, expecting to see the cert specified by the alias. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jlaskey at openjdk.java.net Tue Nov 17 20:04:11 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 20:04:11 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators Message-ID: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . ------------- Commit messages: - 8248862: Implement Enhanced Pseudo-Random Number Generators - Merge branch 'master' into 8248862 - Merge branch 'master' into 8248862 - 8248862: Implement Enhanced Pseudo-Random Number Generators - Merge branch 'master' into 8248862 - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862; Implement Enhanced Pseudo-Random Number Generators - Merge branch 'master' into 8248862 - 8248862: Implement Enhanced Pseudo-Random Number Generators - Merge branch 'master' into 8248862 - ... and 27 more: https://git.openjdk.java.net/jdk/compare/9efbb463...7469ca58 Changes: https://git.openjdk.java.net/jdk/pull/1273/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1273&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8248862 Stats: 14875 lines in 31 files changed: 11094 ins; 3704 del; 77 mod Patch: https://git.openjdk.java.net/jdk/pull/1273.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1273/head:pull/1273 PR: https://git.openjdk.java.net/jdk/pull/1273 From erikj at openjdk.java.net Tue Nov 17 20:18:08 2020 From: erikj at openjdk.java.net (Erik Joelsson) Date: Tue, 17 Nov 2020 20:18:08 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> Message-ID: On Tue, 17 Nov 2020 19:58:47 GMT, Jim Laskey wrote: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . It looks like you have deleted the doc directory. That can't be right? ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Tue Nov 17 20:43:03 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 20:43:03 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> Message-ID: On Tue, 17 Nov 2020 20:15:34 GMT, Erik Joelsson wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > It looks like you have deleted the doc directory. That can't be right? @erikj79 That's possible I had an intermediate doc folder before the master doc was added. I though I was careful to resolve conflict by selecting master but it might be that I picked the wrong one. Will try and correct in next round,. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From xuelei at openjdk.java.net Tue Nov 17 20:49:04 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Tue, 17 Nov 2020 20:49:04 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 19:47:37 GMT, Jamil Nimeh wrote: >> test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 583: >> >>> 581: serverParameters.put(ParamType.CERTALIAS, "EE_ED25519"); >>> 582: runtest(testFormat, isPeerEd25519, null, null, null); >>> 583: serverParameters.remove(ParamType.CERTALIAS); >> >> I did not get the idea here. Is there a special case in practice that use a similar key manger like the AliasKeyManager? > > Right now, for TLS 1.0/1.1 EC certificates will be favored over EdDSA certificates in keystores that have valid certificates with both kinds of keys. There's nothing we can do about that because 1.0/1.1 has no signaling mechanism to indicate signature preference like 1.2+ has. Given that, I was thinking of ways to get around that restriction and one case I thought of was the Tomcat connector, which has options to specify a certificate for use by alias. I wanted to make sure that we could still do that for 1.0/1.1 and it wouldn't break so I cooked up this simple KeyManager and ran a basic connection, expecting to see the cert specified by the alias. Got it. Thanks! ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jlaskey at openjdk.java.net Tue Nov 17 21:03:18 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 21:03:18 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> Message-ID: <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> On Tue, 17 Nov 2020 20:15:34 GMT, Erik Joelsson wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > It looks like you have deleted the doc directory. That can't be right? @erikj79 my local branch seems to have the right sources for doc @erikj79 https://github.com/JimLaskey/jdk/tree/8248862 ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Tue Nov 17 21:03:18 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 21:03:18 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v2] In-Reply-To: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> Message-ID: <_AerudoiREbI3Qj9VRi5zoiogsiCWPD17HhkIvTTCaw=.be7f1fa8-3c1c-49ca-90ba-96b010033087@github.com> > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: 8248862: Implement Enhanced Pseudo-Random Number Generators Updated RandomGeneratorFactory javadoc. ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1273/files - new: https://git.openjdk.java.net/jdk/pull/1273/files/7469ca58..b24024bb Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1273&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1273&range=00-01 Stats: 39 lines in 6 files changed: 16 ins; 0 del; 23 mod Patch: https://git.openjdk.java.net/jdk/pull/1273.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1273/head:pull/1273 PR: https://git.openjdk.java.net/jdk/pull/1273 From kcr at openjdk.java.net Tue Nov 17 21:14:06 2020 From: kcr at openjdk.java.net (Kevin Rushforth) Date: Tue, 17 Nov 2020 21:14:06 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> Message-ID: On Tue, 17 Nov 2020 20:56:52 GMT, Jim Laskey wrote: > my local branch seems to have the right sources for doc Maybe, but your branch on GitHub does not. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From ihse at openjdk.java.net Tue Nov 17 21:38:04 2020 From: ihse at openjdk.java.net (Magnus Ihse Bursie) Date: Tue, 17 Nov 2020 21:38:04 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> Message-ID: On Tue, 17 Nov 2020 21:10:48 GMT, Kevin Rushforth wrote: >> @erikj79 my local branch seems to have the right sources for doc > >> my local branch seems to have the right sources for doc > > Maybe, but your branch on GitHub does not. This PR looks seriously messed up: JimLaskey added 30 commits on Oct 9 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators 515a5a4 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 7c25f2d @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 642022d @JimLaskey Merge branch 'master' into 8248862 b537e0f @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? ca90d01 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? ec2941a @JimLaskey Merge branch 'master' into 8248862 dbe142c @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? cca6f0f @JimLaskey Merge branch 'master' into 8248862 93ee16f @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 84d4704 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? b50f2ee @JimLaskey Merge branch 'master' into 8248862 b1d6abe @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 8afe7a2 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 2f99696 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 7c58819 @JimLaskey Merge branch 'master' into 8248862 655ad08 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? d5860b9 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 3ac78f8 @JimLaskey Merge branch 'master' into 8248862 e3b6e64 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 8ec7f87 @JimLaskey Merge branch 'master' into 8248862 ed959f8 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 72195e8 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 84730c3 @JimLaskey Merge branch 'master' into 8248862 05f0477 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 7dd81ac @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 38f534b @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? f428b61 @JimLaskey Merge branch 'master' into 8248862 5e33872 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 0bc8e3d @JimLaskey Merge branch 'master' into 8248862 679f1b5 JimLaskey added 7 commits 4 days ago @JimLaskey 8248862; Implement Enhanced Pseudo-Random Number Generators ? 17972a9 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 4f0338f @JimLaskey Merge branch 'master' into 8248862 7c6b9fa @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? c67c729 @JimLaskey Merge branch 'master' into 8248862 108ea50 @JimLaskey Merge branch 'master' into 8248862 1b31205 @JimLaskey 8248862: Implement Enhanced Pseudo-Random Number Generators ? 7469ca5 It might be better if you close this, rebase your actual change on top of a current master, and open a new PR instead. The only reason this was flagged with the `build` label was due to the incorrect deletion of doc, so if you intend to go on with this PR, please remove the label after you've fixed the doc issue. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From ihse at openjdk.java.net Tue Nov 17 21:38:04 2020 From: ihse at openjdk.java.net (Magnus Ihse Bursie) Date: Tue, 17 Nov 2020 21:38:04 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> Message-ID: On Tue, 17 Nov 2020 21:33:13 GMT, Magnus Ihse Bursie wrote: >>> my local branch seems to have the right sources for doc >> >> Maybe, but your branch on GitHub does not. > > This PR looks seriously messed up: > > JimLaskey added 30 commits on Oct 9 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators > 515a5a4 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 7c25f2d > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 642022d > @JimLaskey > Merge branch 'master' into 8248862 > b537e0f > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > ca90d01 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > ec2941a > @JimLaskey > Merge branch 'master' into 8248862 > dbe142c > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > cca6f0f > @JimLaskey > Merge branch 'master' into 8248862 > 93ee16f > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 84d4704 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > b50f2ee > @JimLaskey > Merge branch 'master' into 8248862 > b1d6abe > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 8afe7a2 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 2f99696 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 7c58819 > @JimLaskey > Merge branch 'master' into 8248862 > 655ad08 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > d5860b9 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 3ac78f8 > @JimLaskey > Merge branch 'master' into 8248862 > e3b6e64 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 8ec7f87 > @JimLaskey > Merge branch 'master' into 8248862 > ed959f8 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 72195e8 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 84730c3 > @JimLaskey > Merge branch 'master' into 8248862 > 05f0477 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 7dd81ac > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 38f534b > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > f428b61 > @JimLaskey > Merge branch 'master' into 8248862 > 5e33872 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 0bc8e3d > @JimLaskey > Merge branch 'master' into 8248862 > 679f1b5 > JimLaskey added 7 commits 4 days ago > @JimLaskey > 8248862; Implement Enhanced Pseudo-Random Number Generators ? > 17972a9 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 4f0338f > @JimLaskey > Merge branch 'master' into 8248862 > 7c6b9fa > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > c67c729 > @JimLaskey > Merge branch 'master' into 8248862 > 108ea50 > @JimLaskey > Merge branch 'master' into 8248862 > 1b31205 > @JimLaskey > 8248862: Implement Enhanced Pseudo-Random Number Generators ? > 7469ca5 > > It might be better if you close this, rebase your actual change on top of a current master, and open a new PR instead. > > The only reason this was flagged with the `build` label was due to the incorrect deletion of doc, so if you intend to go on with this PR, please remove the label after you've fixed the doc issue. Ah, sorry, I see now that I expanded the commit comments that it was not just the same commit applied over and over again, as I assumed, but iterative steps from your branch while developing, that just had the same first line... sorry for the confusion about that. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From WEIJUN.WANG at ORACLE.COM Tue Nov 17 21:38:31 2020 From: WEIJUN.WANG at ORACLE.COM (Weijun Wang) Date: Tue, 17 Nov 2020 16:38:31 -0500 Subject: RFR 8153005: Upgrade the default PKCS12 encryption/MAC algorithms In-Reply-To: <907C5852-0A7B-493F-8A8D-A8EB4B57D67B@oracle.com> References: <907C5852-0A7B-493F-8A8D-A8EB4B57D67B@oracle.com> Message-ID: > On Apr 10, 2020, at 5:03 AM, Weijun Wang wrote: > > Please take a review at > > CSR : 8228481: Upgrade the default PKCS12 encryption/MAC algorithms > Release note : https://bugs.openjdk.java.net/browse/JDK-8242069 I forget if the release note has been reviewed before. If not, please take a look. Thanks, Max > webrev : http://cr.openjdk.java.net/~weijun/8153005/webrev.00/ > > The default pkcs12 algorithms are bumped into PBE and HMAC based on SHA-256 and AES-256. > > Thanks, > Max > From weijun at openjdk.java.net Tue Nov 17 21:39:05 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 17 Nov 2020 21:39:05 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v3] In-Reply-To: References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <8QmQCRuCgM-VXtCD_nmlfqoGTWl4DlYJAVjwkJYwfu0=.e5486131-9678-4386-8a3c-c65624be2fdb@github.com> Message-ID: On Tue, 17 Nov 2020 19:36:31 GMT, Sean Mullan wrote: >> New commit and the output will look like: >> PSSParameterSpec[hashAlgorithm=SHA-256, maskGenAlgorithm=MGF1ParameterSpec[hashAlgorithm=SHA-256], saltLength=32, trailerField=1] >> I'm using the ASN.1 field names here. (Precisely the name in MGF1 is OAEP-PSSDigestAlgorithms but that's too long). > >> New commit and the output will look like: >> >> ``` >> PSSParameterSpec[hashAlgorithm=SHA-256, maskGenAlgorithm=MGF1ParameterSpec[hashAlgorithm=SHA-256], saltLength=32, trailerField=1] >> ``` >> >> I'm using the ASN.1 field names here. (Precisely the name in MGF1 is OAEP-PSSDigestAlgorithms but that's too long). > > I like it. Looks good. @seanjmullan Can you approve it then? ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From weijun at openjdk.java.net Tue Nov 17 21:51:22 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Tue, 17 Nov 2020 21:51:22 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 Message-ID: This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). ------------- Commit messages: - 8256507: Add a micro benchmark for JDK-8153005 Changes: https://git.openjdk.java.net/jdk/pull/1277/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1277&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256507 Stats: 199 lines in 1 file changed: 199 ins; 0 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/1277.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1277/head:pull/1277 PR: https://git.openjdk.java.net/jdk/pull/1277 From jlaskey at openjdk.java.net Tue Nov 17 22:02:11 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 22:02:11 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> Message-ID: On Tue, 17 Nov 2020 21:10:48 GMT, Kevin Rushforth wrote: >> @erikj79 my local branch seems to have the right sources for doc > >> my local branch seems to have the right sources for doc > > Maybe, but your branch on GitHub does not. @kevinrushforth What is the recommended approach to remove the doc edit/commit? ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Tue Nov 17 22:15:03 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 22:15:03 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> Message-ID: On Tue, 17 Nov 2020 21:59:04 GMT, Jim Laskey wrote: >>> my local branch seems to have the right sources for doc >> >> Maybe, but your branch on GitHub does not. > > @kevinrushforth What is the recommended approach to remove the doc edit/commit? javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Tue Nov 17 22:21:18 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 17 Nov 2020 22:21:18 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> Message-ID: <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: - Merge branch 'master' into 8248862 - 8248862: Implement Enhanced Pseudo-Random Number Generators Update package-info.java - 8248862: Implement Enhanced Pseudo-Random Number Generators Updated RandomGeneratorFactory javadoc. - 8248862: Implement Enhanced Pseudo-Random Number Generators Updated documentation for RandomGeneratorFactory. - Merge branch 'master' into 8248862 - Merge branch 'master' into 8248862 - 8248862: Implement Enhanced Pseudo-Random Number Generators Move RandomGeneratorProperty - Merge branch 'master' into 8248862 - 8248862: Implement Enhanced Pseudo-Random Number Generators Clear up javadoc - 8248862; Implement Enhanced Pseudo-Random Number Generators remove RandomGeneratorProperty from API - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 ------------- Changes: https://git.openjdk.java.net/jdk/pull/1273/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1273&range=02 Stats: 14891 lines in 31 files changed: 11110 ins; 3704 del; 77 mod Patch: https://git.openjdk.java.net/jdk/pull/1273.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1273/head:pull/1273 PR: https://git.openjdk.java.net/jdk/pull/1273 From kcr at openjdk.java.net Tue Nov 17 22:54:06 2020 From: kcr at openjdk.java.net (Kevin Rushforth) Date: Tue, 17 Nov 2020 22:54:06 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <3vhrOZBGrwfQVyPxA_qi7l_gimy0RqkPIRDHR7rm3SE=.79a40273-6ed4-474f-9b1e-30bd6845d303@github.com> Message-ID: On Tue, 17 Nov 2020 22:12:19 GMT, Jim Laskey wrote: >> @kevinrushforth What is the recommended approach to remove the doc edit/commit? > > javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html Presuming your master branch is in sync with the upstream jdk repo, something like the following: git checkout master -- doc git add doc git commit -m "restore doc files" ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From ascarpino at openjdk.java.net Tue Nov 17 22:58:12 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Tue, 17 Nov 2020 22:58:12 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Thu, 12 Nov 2020 20:17:39 GMT, Valerie Peng wrote: >> checkOutputCapacity: Yes.. The method includes the offsets for the output buffer, which I believe would verify that the output area in the buffer with offsets is large enough. >> >> outWithPadding: I understand the situation and I am assuming there are tests that cover this case. Given it's a generic situation. > > Have you tested the outWithPadding situation? Given that the existing impl only write out the final result, I don't think you can assume that existing tests cover it. I have wrote a simple test to check it if you have not done so, can you try it out to be sure? > > import java.io.PrintStream; > import java.util.*; > import java.security.*; > import java.security.spec.*; > > import javax.crypto.*; > import javax.crypto.spec.*; > > public class TestDoFinal { > > private static String ALGO = "AES"; > private static int BLK_SIZE = 16; > > public static void main(String args[]) throws Exception { > > byte[] in = new byte[32]; > Arrays.fill(in, (byte)8); > KeyGenerator kg = KeyGenerator.getInstance(ALGO, "SunJCE"); > SecretKey skey = kg.generateKey(); > Cipher ci = Cipher.getInstance(ALGO + "/CBC/PKCS5Padding", "SunJCE"); > ci.init(Cipher.ENCRYPT_MODE, skey); > int inLen = in.length - BLK_SIZE; > byte[] out = ci.doFinal(in, 0, inLen); > System.out.println("=> enc " + inLen + " bytes, ret " + > (out == null? "null":(out.length + " byte"))); > > AlgorithmParameters param = ci.getParameters(); > ci.init(Cipher.DECRYPT_MODE, skey, param); > int rLen = ci.doFinal(out, 0, out.length, in); > System.out.println("=> dec " + out.length + " bytes, ret " + > rLen + " byte"); > // check if more than rLen bytes are written into 'in' > for (int j = rLen; j < in.length; j++) { > if (in[j] != (byte)8) { > throw new Exception("Value check failed at index " + j); > } > } > System.out.println("Test Passed"); > } > } I tried to fix this, and I did for this test, but there other situations with update() that weren't working. It would take some reworking of a few common methods during the doFinal process to handle this right. I'm going to put an 'if()" so non-GCM modes create a new buffer like it did before. It was a "nice to have' for this rfe that can be done with future work for other mode optimizations. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Tue Nov 17 23:24:13 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Tue, 17 Nov 2020 23:24:13 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: References: Message-ID: On Fri, 6 Nov 2020 23:02:54 GMT, Valerie Peng wrote: >> If the output buffer provided is not big enough, it creates an internal one. Two things happened here, one the variable was renamed because I felt "outWithPadding" was misleading. The second was to only create this buffer when the length was smaller than the estimated length. Before this change it would already create and use this buffer whether it was needed or not. > > I understand the renaming and etc. The difference here is that if output buffer is large enough, then the padding bytes are written into the output buffer even though the returned output length does not count them. Before this change, a separate output buffer is always used. Do you think it's ok to output padding bytes into user-supplied buffer? This is my main concern about this line. With me reverting padding ciphers to having a copy again, this should not be a concern. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Tue Nov 17 23:32:17 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Tue, 17 Nov 2020 23:32:17 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: <2gfKNtUb1TOpRCFwFY9ZxZy9GxyypI1KCk0OX3WGtHo=.08e701c7-3e2d-4734-8dba-9db36700f79f@github.com> References: <2gfKNtUb1TOpRCFwFY9ZxZy9GxyypI1KCk0OX3WGtHo=.08e701c7-3e2d-4734-8dba-9db36700f79f@github.com> Message-ID: On Fri, 6 Nov 2020 23:08:10 GMT, Valerie Peng wrote: >> I does not. CipherCore only sends block sized data, and the ByteBuffer code uses this method during final operations. > > Hmm, ok, this is getting obscure and the correctness is depending on the calling pattern. Can we add a check on line 514 to ensure that there is no bytes in ibuffer? This got added into v3 ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From jnimeh at openjdk.java.net Tue Nov 17 23:34:13 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Tue, 17 Nov 2020 23:34:13 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 18:32:34 GMT, Xue-Lei Andrew Fan wrote: >> Hello all, >> This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. > > test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 92: > >> 90: final SessionChecker serverChecker; >> 91: final Class clientException; >> 92: final Class serverException; > > If no problem, I may declare the class fields and inner classes as private for safe. OK. Will do. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Tue Nov 17 23:34:11 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Tue, 17 Nov 2020 23:34:11 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 19:43:25 GMT, Jamil Nimeh wrote: >> test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java line 81: >> >>> 79: static final String DEF_ALL_EE = "EE_ECDSA_SECP256R1:EE_ECDSA_SECP384R1:" + >>> 80: "EE_ECDSA_SECP521R1:EE_RSA_2048:EE_EC_RSA_SECP256R1:" + >>> 81: "EE_DSA_2048:EE_DSA_1024:EE_ED25519:EE_ED448"; >> >> Why not use enum, array or collection directly? Which is easy to read, I think. > > I don't think there's any reason why we could use a Collection for these. I'll try switching to that. Xuelei, I went back and looked at my rationale for using Strings here. The reason I went with this approach was so I could have client and server parameter maps of . I had a common form for parameters that I'd want to set/reset/change between each type of test run. If I were to go with something like a Collection then my client and server parameter maps would end up needing to be and then I'd have to cast based on the param type. Not sure if changing from the Strings ends up being more clear int the long run. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From xuelei at openjdk.java.net Tue Nov 17 23:45:12 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Tue, 17 Nov 2020 23:45:12 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Tue, 17 Nov 2020 23:31:13 GMT, Jamil Nimeh wrote: >> I don't think there's any reason why we could use a Collection for these. I'll try switching to that. > > Xuelei, I went back and looked at my rationale for using Strings here. The reason I went with this approach was so I could have client and server parameter maps of . I had a common form for parameters that I'd want to set/reset/change between each type of test run. If I were to go with something like a Collection then my client and server parameter maps would end up needing to be and then I'd have to cast based on the param type. Not sure if changing from the Strings ends up being more clear int the long run. No problem, using String is ok to me. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Wed Nov 18 00:00:24 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Wed, 18 Nov 2020 00:00:24 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v2] In-Reply-To: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: > Hello all, > This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains five additional commits since the last revision: - Merge - Applied code review comments to tests - Fix cut/paste error with ECDH-RSA key exchange - Merge - Initial EdDSA/TLS solution ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1197/files - new: https://git.openjdk.java.net/jdk/pull/1197/files/3396e6c2..59aced35 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=00-01 Stats: 19865 lines in 433 files changed: 12225 ins; 5055 del; 2585 mod Patch: https://git.openjdk.java.net/jdk/pull/1197.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1197/head:pull/1197 PR: https://git.openjdk.java.net/jdk/pull/1197 From psandoz at openjdk.java.net Wed Nov 18 00:54:18 2020 From: psandoz at openjdk.java.net (Paul Sandoz) Date: Wed, 18 Nov 2020 00:54:18 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> Message-ID: <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> On Tue, 17 Nov 2020 22:21:18 GMT, Jim Laskey wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: > > - Merge branch 'master' into 8248862 > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Update package-info.java > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Updated RandomGeneratorFactory javadoc. > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Updated documentation for RandomGeneratorFactory. > - Merge branch 'master' into 8248862 > - Merge branch 'master' into 8248862 > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Move RandomGeneratorProperty > - Merge branch 'master' into 8248862 > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Clear up javadoc > - 8248862; Implement Enhanced Pseudo-Random Number Generators > > remove RandomGeneratorProperty from API > - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 I am unsure if the intent is also to support external libraries providing `RandomGenerator` implementations. Currently there is an implicit contract for properties (reflectively invoking a method returning a map with a set of entries with known keys). Since the service provider implementation is the `RandomGenerator` itself, rather than `RandomGeneratorFactory` it is harder expose the meta-data with a clearer contract. src/java.base/share/classes/java/util/Random.java line 592: > 590: > 591: @Override > 592: public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) { Unsure if this and the other two methods are intended to be public or not, since they are at the end of the class and override methods of a module private class. In principle there is nothing wrong with such `Spliterator` factories, but wonder if they are really needed given the `Stream` returning methods. The arrangement of classes makes it awkward to hide these methods. src/java.base/share/classes/java/util/SplittableRandom.java line 171: > 169: * RandomGenerator properties. > 170: */ > 171: static Map getProperties() { With records exiting preview in 16 this map of properties could i think be represented as a record instance, with better type safety, where `RandomSupport.RandomGeneratorProperty` enum values become typed fields declared on the record class. Something to consider after integration perhaps? src/java.base/share/classes/java/util/SplittableRandom.java line 211: > 209: * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html > 210: */ > 211: private static long mix64(long z) { Usages be replaced with calls to `RandomSupport.mixStafford13`? src/java.base/share/classes/module-info.java line 250: > 248: exports jdk.internal.util.xml.impl to > 249: jdk.jfr; > 250: exports jdk.internal.util.random; Unqualified export, should this be `to jdk.random`? src/jdk.random/share/classes/module-info.java line 50: > 48: */ > 49: module jdk.random { > 50: uses java.util.random.RandomGenerator; Are these `uses` declarations needed? `ServiceLoader` is not used by this module, and `RandomSupport` is not a service interface. src/jdk.random/share/classes/module-info.java line 53: > 51: uses RandomSupport; > 52: > 53: exports jdk.random to Why is this needed? src/java.base/share/classes/java/util/random/package-info.java line 50: > 48: * given its name. > 49: * > 50: *

The principal supporting class is {@link RandomGenertatorFactor}. This s/RandomGenertatorFactor/RandomGenertatorFactory src/java.base/share/classes/java/util/random/package-info.java line 140: > 138: * > 139: *

For applications with no special requirements, > 140: * "L64X128MixRandom" has a good balance among speed, space, The documentation assumes that the `jdk.random` module is present in the JDK image. Perhaps we need to spit the specifics to `jdk.random`? src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 1211: > 1209: Udiff = -Udiff; > 1210: U2 = U1; > 1211: U1 -= Udiff; Updated `U1` never used (recommend running the code through a checker e.g. use IntelliJ) src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 331: > 329: } > 330: // Finally, we need to make sure the last z words are not all zero. > 331: search: { Nice! a rarely used feature :-) src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 1157: > 1155: /* > 1156: * The tables themselves, as well as a number of associated parameters, are > 1157: * defined in class java.util.DoubleZigguratTables, which is automatically `DoubleZigguratTables` is an inner class of `RandomSupport` src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 2895: > 2893: * distribution: 0.0330 > 2894: */ > 2895: static class DoubleZigguratTables { make `final` src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 167: > 165: * Return the properties map for the specified provider. > 166: * > 167: * @param provider provider to locate. Method has no such parameter src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 173: > 171: @SuppressWarnings("unchecked") > 172: private Map getProperties() { > 173: if (properties == null) { `properties` needs to be marked volatile, and it needs to be assigned at line 182 or line 184. src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 148: > 146: */ > 147: private static Map> getFactoryMap() { > 148: if (factoryMap == null) { `factoryMap` needs to be marked volatile when using the double checked locking idiom. src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 320: > 318: } > 319: } > 320: } Add an `assert` statement that `ctor`, `ctorLong` and `ctorBytes` are all non-null? src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 331: > 329: */ > 330: private void ensureConstructors() { > 331: if (ctor == null) { This check occurs outside of the synchronized block, field may need to be marked volatile. Unsure about the other dependent fields. Might need to store values from loop in `getConstructors` in locals and then assign in appropriate order, assigning the volatile field last. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From ascarpino at openjdk.java.net Wed Nov 18 02:54:14 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Wed, 18 Nov 2020 02:54:14 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v3] In-Reply-To: <2gfKNtUb1TOpRCFwFY9ZxZy9GxyypI1KCk0OX3WGtHo=.08e701c7-3e2d-4734-8dba-9db36700f79f@github.com> References: <2gfKNtUb1TOpRCFwFY9ZxZy9GxyypI1KCk0OX3WGtHo=.08e701c7-3e2d-4734-8dba-9db36700f79f@github.com> Message-ID: <8X3bg2Q4Ee5r5P9n7XIXqi6xqwCEtiNuKlvhnD0H3lY=.d4d36ff6-e50d-4355-8ef9-8e6565953350@github.com> On Fri, 6 Nov 2020 23:09:31 GMT, Valerie Peng wrote: >> This is not an optimized path for bytebuffers and will never have any data in ibuffer. > > Hmm, ok, can we add a check on ibuffer size here just to be sure? I've rewritten checkDataLength so it can include more values to calculate. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Wed Nov 18 04:31:12 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Wed, 18 Nov 2020 04:31:12 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: <1Goe8AGkytjQmXHg4xSkxj7WtKWoIXlJUvUsVJQIB8k=.cce1b9d5-26f0-46de-b095-9d3230ac4714@github.com> On Mon, 16 Nov 2020 19:17:55 GMT, Valerie Peng wrote: >> This is a very seldom used code path, There was only one existing test that accesses this code and it has not offset. >> >> constructBlock() is a generic method. There should be no case where ibuffer is >= blocksize during this method. For encryption the two encrypt() only put code in ibuffer. This method is for normal update() operations. The other encrypt is for any of the CipherCore internal buffer needs sent to GCM before doing the doFinal. At that point, ibuffer can be >= blocksize and doFinal will handle it. Some of this complication will go away with phase 2 of separating GCM from CipherCore > > The current impl of constructBlock() seems to have code handling ibuffer >= blocksize scenario. Could you fix that and also pass the input offset into constructBlock() for this RFE? I redid the whole code ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Wed Nov 18 05:17:15 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Wed, 18 Nov 2020 05:17:15 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Mon, 16 Nov 2020 19:23:20 GMT, Valerie Peng wrote: >> You don't know what 'len', which includes ibuffer data, until this point in the code. > > Well, didn't you already calcuate the 'len' value in the beginning of the copied-from-GCTR RuntimeException check? I'm removing the runtime check in the next update, it was duplicate of the ShortBufferException. Calculating 'len' through the if() above line 818 while it is prepares the bytebuffers is good enough. >> I thought so too, but that isn't what GCTR returns. All the GCTR checks are RuntimeExceptions. This check was original inside of GCTR, but I had to bring it out because of the ibuffer lengths. I don't mind changing, it's just a strange inconsistency. > > GaloisCounterMode is the caller class of GCTR and this API is meant to throw ShortBufferException I think (based on the check at lines below at 820-822)... Yes.. this check is not necessary given the ShortBufferException was already checked. I am removing this as part of the next update ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From ascarpino at openjdk.java.net Wed Nov 18 05:17:16 2020 From: ascarpino at openjdk.java.net (Anthony Scarpino) Date: Wed, 18 Nov 2020 05:17:16 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Fri, 13 Nov 2020 21:00:20 GMT, Valerie Peng wrote: >> Anthony Scarpino has updated the pull request incrementally with one additional commit since the last revision: >> >> Code review comment update >> Major change to test to detect corruption with incremental buffers test > > src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 560: > >> 558: System.arraycopy(buffer, 0, block, 0, blockSize); >> 559: buflen -= block.length; >> 560: return 0; > > Will bufLen > blockSize? Judging from the context of this method, buffer.length should always <= blockSize and never be larger? If bufLen == blockSize, perhaps we can just use buffer directly and no need to copy. This method is being removed ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From shade at openjdk.java.net Wed Nov 18 10:15:10 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Wed, 18 Nov 2020 10:15:10 GMT Subject: RFR: 8256523: Streamline Java SHA2 implementation Message-ID: Current `sun/security/provider/SHA2` implementation is written with lots of small method invocations on the fastpath in `implCompress0`. Normally it does not matter much, because compilers are able to inline through it, and then some compilers even intrinsify the entire `implCompress0`. But it comes as major downside for platforms that do not have SHA2 intrinsics, or those VM configs that blindly interpret the bytecode. Zero, for example, keeps re-entering the small methods when computing SHA2 digests during jmod/jlink generation during the build, and spends significant time there. Linux x86_64 Zero fastdebug builds **improve from 18.5 minutes to 11.0 minutes** with this change, which is a major win for development experience. Note that SHA1 is already written in similar streamlined style. SHA5 is written with helper functions. This patch moves SHA2 to be closer to SHA1 style-wise. Performance improvement in interpreted modes is substantial, about 4x..5x, while compiler modes are not affected. As measured by: `make test TEST="micro:MessageDigests" MICRO="FORK=1;ITER=5;WARMUP_ITER=5;WARMUP_TIME=1s;TIME=1s;OPTIONS=-p digesterName=sha256 -p provider=SUN"` Before: Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units # Server, Default MessageDigests.digest sha256 64 SUN thrpt 5 8585.532 ? 219.896 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 1545.994 ? 73.325 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 110.550 ? 1.576 ops/ms # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics MessageDigests.digest sha256 64 SUN thrpt 5 1426.117 ? 48.320 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 188.779 ? 0.097 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 12.512 ? 1.371 ops/ms # Server, -Xint MessageDigests.digest sha256 64 SUN thrpt 5 6.143 ? 0.126 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 0.769 ? 0.008 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 0.051 ? 0.001 ops/ms # Zero MessageDigests.digest sha256 64 SUN thrpt 5 5.358 ? 0.664 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 0.686 ? 0.003 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 0.046 ? 0.001 ops/ms After: Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units # Server, Default MessageDigests.digest sha256 64 SUN thrpt 5 8564.689 ? 1459.552 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 1548.582 ? 78.888 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 110.800 ? 0.057 ops/ms # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics MessageDigests.digest sha256 64 SUN thrpt 5 1471.399 ? 66.622 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 186.297 ? 0.127 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 12.448 ? 0.099 ops/ms # Server, -Xint MessageDigests.digest sha256 64 SUN thrpt 5 27.046 ? 0.304 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 3.538 ? 0.060 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 0.238 ? 0.002 ops/ms # Zero MessageDigests.digest sha256 64 SUN thrpt 5 26.696 ? 0.968 ops/ms MessageDigests.digest sha256 1024 SUN thrpt 5 3.655 ? 0.024 ops/ms MessageDigests.digest sha256 16384 SUN thrpt 5 0.241 ? 0.002 ops/ms Addtional testing: - [x] `jdk/security` with Linux x86_64 server fastdebug - [x] `jdk/security` with Linux x86_64 zero fastdebug ------------- Commit messages: - 8256523: Streamline Java SHA2 implementation Changes: https://git.openjdk.java.net/jdk/pull/1283/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1283&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256523 Stats: 123 lines in 1 file changed: 41 ins; 78 del; 4 mod Patch: https://git.openjdk.java.net/jdk/pull/1283.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1283/head:pull/1283 PR: https://git.openjdk.java.net/jdk/pull/1283 From mullan at openjdk.java.net Wed Nov 18 13:03:08 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Wed, 18 Nov 2020 13:03:08 GMT Subject: RFR: 8256363: Define toString() for MGF1ParameterSpec [v3] In-Reply-To: <3pbjCPvkbyoGC-c6gOFCUXD0nQxEp6qPswDrmqRn2dE=.b5f46930-ba57-4e2f-b8dd-439f8fbd8a6b@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> <3pbjCPvkbyoGC-c6gOFCUXD0nQxEp6qPswDrmqRn2dE=.b5f46930-ba57-4e2f-b8dd-439f8fbd8a6b@github.com> Message-ID: <6wQ78P6UZIKw8pMIee2PIxG1JPhMnZjXxuREx3a4RBM=.649d1b74-28a1-4896-a2a8-739f1dbf7f9f@github.com> On Tue, 17 Nov 2020 15:37:18 GMT, Weijun Wang wrote: >> Without this method, `PSSParameterSpec::toString` shows something like: >> MD: SHA-256 >> MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 >> SaltLength: 32 >> TrailerField: 1 >> This is ugly. >> >> Noreg-trivial. > > Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: > > choose a record-style format Marked as reviewed by mullan (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From weijun at openjdk.java.net Wed Nov 18 13:17:01 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Wed, 18 Nov 2020 13:17:01 GMT Subject: Integrated: 8256363: Define toString() for MGF1ParameterSpec In-Reply-To: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> References: <7fftn4RXkSz0c-AoQbJngsuuDRYcj3eXEEzB6MW73w0=.56fb3cb8-a87c-452e-a2a1-0a3a72b39157@github.com> Message-ID: <9_xvP5I6ADyrcB1LIb5S4Vsv0xxa2eYXtNbM0u4YC0k=.d2ccb609-5a9d-48be-bd07-107ddbda651e@github.com> On Fri, 13 Nov 2020 21:13:54 GMT, Weijun Wang wrote: > Without this method, `PSSParameterSpec::toString` shows something like: > MD: SHA-256 > MGF: java.security.spec.MGF1ParameterSpec at 77b52d12 > SaltLength: 32 > TrailerField: 1 > This is ugly. > > Noreg-trivial. This pull request has now been integrated. Changeset: 486d6f63 Author: Weijun Wang URL: https://git.openjdk.java.net/jdk/commit/486d6f63 Stats: 17 lines in 3 files changed: 6 ins; 2 del; 9 mod 8256363: Define toString() for MGF1ParameterSpec Reviewed-by: mullan ------------- PR: https://git.openjdk.java.net/jdk/pull/1208 From jlaskey at openjdk.java.net Wed Nov 18 13:21:11 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Wed, 18 Nov 2020 13:21:11 GMT Subject: Withdrawn: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> Message-ID: <0ehbQoBJaglOxi_fA4XXjjVbL4iXPwj8wz-W9aoW6I8=.5a76bd44-9a20-4e29-b9d9-5f21548df415@github.com> On Tue, 17 Nov 2020 19:58:47 GMT, Jim Laskey wrote: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . This pull request has been closed without being integrated. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Wed Nov 18 13:21:10 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Wed, 18 Nov 2020 13:21:10 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: On Wed, 18 Nov 2020 00:51:43 GMT, Paul Sandoz wrote: >> Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: >> >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Update package-info.java >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated RandomGeneratorFactory javadoc. >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated documentation for RandomGeneratorFactory. >> - Merge branch 'master' into 8248862 >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Move RandomGeneratorProperty >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Clear up javadoc >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> >> remove RandomGeneratorProperty from API >> - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 > > I am unsure if the intent is also to support external libraries providing `RandomGenerator` implementations. Currently there is an implicit contract for properties (reflectively invoking a method returning a map with a set of entries with known keys). Since the service provider implementation is the `RandomGenerator` itself, rather than `RandomGeneratorFactory` it is harder expose the meta-data with a clearer contract. Need rebase ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Wed Nov 18 13:48:04 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Wed, 18 Nov 2020 13:48:04 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: <5IW2VsaVaqCMqkD6qkNxdWpL1qJM8daN1yf9a-Ivxk8=.d15e95c1-183d-4d50-98ff-e112beadf602@github.com> On Wed, 18 Nov 2020 13:18:30 GMT, Jim Laskey wrote: >> I am unsure if the intent is also to support external libraries providing `RandomGenerator` implementations. Currently there is an implicit contract for properties (reflectively invoking a method returning a map with a set of entries with known keys). Since the service provider implementation is the `RandomGenerator` itself, rather than `RandomGeneratorFactory` it is harder expose the meta-data with a clearer contract. > > Need rebase Created new PR because of forced push: https://github.com/openjdk/jdk/pull/1292 ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Wed Nov 18 13:52:56 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Wed, 18 Nov 2020 13:52:56 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators Message-ID: This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html old PR: https://github.com/openjdk/jdk/pull/1273 ------------- Commit messages: - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862; Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - 8248862: Implement Enhanced Pseudo-Random Number Generators - ... and 15 more: https://git.openjdk.java.net/jdk/compare/f7517386...2b3e4ed7 Changes: https://git.openjdk.java.net/jdk/pull/1292/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8248862 Stats: 13319 lines in 25 files changed: 11110 ins; 2132 del; 77 mod Patch: https://git.openjdk.java.net/jdk/pull/1292.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292 PR: https://git.openjdk.java.net/jdk/pull/1292 From shade at openjdk.java.net Wed Nov 18 13:53:06 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Wed, 18 Nov 2020 13:53:06 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 In-Reply-To: References: Message-ID: On Tue, 17 Nov 2020 21:46:38 GMT, Weijun Wang wrote: > This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). I think the benchmark can be simplified. test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 65: > 63: } > 64: > 65: static { Move these to @Setup public void setup() throws Exception { ... } This would save you a `try-catch` section, and harness would properly fail on setup exception. test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 137: > 135: "PBEWithSHA1AndDESede", "2048", > 136: "HmacPBESHA1", "2048"); > 137: } Any reason why these methods are not inlined into `@Benchmark` methods right away? E.g. why it is not: @Benchmark public byte[] outweak2048() throws Exception { return out("PBEWithSHA1AndRC2_40", "2048", "PBEWithSHA1AndDESede", "2048", "HmacPBESHA1", "2048"); } ------------- Changes requested by shade (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/1277 From weijun at openjdk.java.net Wed Nov 18 14:53:03 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Wed, 18 Nov 2020 14:53:03 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 13:46:04 GMT, Aleksey Shipilev wrote: >> This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). > > test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 65: > >> 63: } >> 64: >> 65: static { > > Move these to > > @Setup > public void setup() throws Exception { > ... > } > > This would save you a `try-catch` section, and harness would properly fail on setup exception. Newbie on JMH. Is it worth designing the byte[] fields as static? I assume there will be different objects for different forks but only one for different threads? > test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 137: > >> 135: "PBEWithSHA1AndDESede", "2048", >> 136: "HmacPBESHA1", "2048"); >> 137: } > > Any reason why these methods are not inlined into `@Benchmark` methods right away? E.g. why it is not: > > @Benchmark > public byte[] outweak2048() throws Exception { > return out("PBEWithSHA1AndRC2_40", "2048", > "PBEWithSHA1AndDESede", "2048", > "HmacPBESHA1", "2048"); > } I want to make the byte[] fields static so the out() and gen***() methods must be static, and there is a warning on using a static method as a `@Benchmark` method. ------------- PR: https://git.openjdk.java.net/jdk/pull/1277 From coffeys at openjdk.java.net Wed Nov 18 15:51:06 2020 From: coffeys at openjdk.java.net (Sean Coffey) Date: Wed, 18 Nov 2020 15:51:06 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 [v2] In-Reply-To: References: Message-ID: On Tue, 17 Nov 2020 17:55:19 GMT, Sean Mullan wrote: >> This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 >> >> The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java > > Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: > > More test changes. Marked as reviewed by coffeys (Reviewer). test/lib/jdk/test/lib/security/SecurityUtils.java line 64: > 62: } > 63: > 64: private static void removeFromDisabledAlgs(String prop, List algs) { Useful utility method. Maybe it can be made public/ opened up and renamed to something like "removeFromSecurityProperty" perhaps ? could be done at a later time perhaps. ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From shade at openjdk.java.net Wed Nov 18 16:04:02 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Wed, 18 Nov 2020 16:04:02 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 14:49:54 GMT, Weijun Wang wrote: >> test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 65: >> >>> 63: } >>> 64: >>> 65: static { >> >> Move these to >> >> @Setup >> public void setup() throws Exception { >> ... >> } >> >> This would save you a `try-catch` section, and harness would properly fail on setup exception. > > Newbie on JMH. Is it worth designing the byte[] fields as static? I assume there will be different objects for different forks but only one for different threads? It does not worth it to make fields `static`. It is much better to let JMH manage the setup, that's what `@Setup` methods are for. If you want to share all instance fields across the thread, then use `@State(Scope.Benchmark)`, it is now `Scope.Thread`. ------------- PR: https://git.openjdk.java.net/jdk/pull/1277 From mullan at openjdk.java.net Wed Nov 18 16:15:06 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Wed, 18 Nov 2020 16:15:06 GMT Subject: RFR: 8202343: Disable TLS 1.0 and 1.1 [v2] In-Reply-To: References: Message-ID: <8d7kZXvZbtr3bb__EFdYXvyjczCVD1Yt-yarynY7Nz4=.513d801a-c827-4372-b69d-c22252451d3a@github.com> On Wed, 18 Nov 2020 15:45:02 GMT, Sean Coffey wrote: >> Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: >> >> More test changes. > > test/lib/jdk/test/lib/security/SecurityUtils.java line 64: > >> 62: } >> 63: >> 64: private static void removeFromDisabledAlgs(String prop, List algs) { > > Useful utility method. Maybe it can be made public/ opened up and renamed to something like "removeFromSecurityProperty" perhaps ? could be done at a later time perhaps. Yes, that's the main reason why I put that code into a separate method, so that we could consider adding more methods that call it or using it more generally in subsequent fixes where we need to re-enable disabled algorithms. ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From weijun at openjdk.java.net Wed Nov 18 18:53:21 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Wed, 18 Nov 2020 18:53:21 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 [v2] In-Reply-To: References: Message-ID: > This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: not static anymore ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1277/files - new: https://git.openjdk.java.net/jdk/pull/1277/files/df96a06e..9247081d Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1277&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1277&range=00-01 Stats: 67 lines in 1 file changed: 0 ins; 28 del; 39 mod Patch: https://git.openjdk.java.net/jdk/pull/1277.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1277/head:pull/1277 PR: https://git.openjdk.java.net/jdk/pull/1277 From weijun at openjdk.java.net Wed Nov 18 18:53:21 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Wed, 18 Nov 2020 18:53:21 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 [v2] In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 13:50:14 GMT, Aleksey Shipilev wrote: >> Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: >> >> not static anymore > > I think the benchmark can be simplified. New commit. No more static fields. Thanks. @shipilev. ------------- PR: https://git.openjdk.java.net/jdk/pull/1277 From valeriep at openjdk.java.net Wed Nov 18 20:03:00 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Wed, 18 Nov 2020 20:03:00 GMT Subject: RFR: 8256523: Streamline Java SHA2 implementation In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 08:29:49 GMT, Aleksey Shipilev wrote: > Current `sun/security/provider/SHA2` implementation is written with lots of small method invocations on the fastpath in `implCompress0`. Normally it does not matter much, because compilers are able to inline through it, and then some compilers even intrinsify the entire `implCompress0`. > > But it comes as major downside for platforms that do not have SHA2 intrinsics, or those VM configs that blindly interpret the bytecode. Zero, for example, keeps re-entering the small methods when computing SHA2 digests during jmod/jlink generation during the build, and spends significant time there. Linux x86_64 Zero fastdebug builds **improve from 18.5 minutes to 11.0 minutes** with this change, which is a major win for development experience. > > Note that SHA1 is already written in similar streamlined style. SHA5 is written with helper functions. This patch moves SHA2 to be closer to SHA1 style-wise. > > Performance improvement in interpreted modes is substantial, about 4x..5x, while compiler modes are not affected. As measured by: `make test TEST="micro:MessageDigests" MICRO="FORK=1;ITER=5;WARMUP_ITER=5;WARMUP_TIME=1s;TIME=1s;OPTIONS=-p digesterName=sha256 -p provider=SUN"` > > Before: > > Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units > > # Server, Default > MessageDigests.digest sha256 64 SUN thrpt 5 8585.532 ? 219.896 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 1545.994 ? 73.325 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 110.550 ? 1.576 ops/ms > > # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics > MessageDigests.digest sha256 64 SUN thrpt 5 1426.117 ? 48.320 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 188.779 ? 0.097 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 12.512 ? 1.371 ops/ms > > # Server, -Xint > MessageDigests.digest sha256 64 SUN thrpt 5 6.143 ? 0.126 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 0.769 ? 0.008 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.051 ? 0.001 ops/ms > > # Zero > MessageDigests.digest sha256 64 SUN thrpt 5 5.358 ? 0.664 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 0.686 ? 0.003 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.046 ? 0.001 ops/ms > > After: > > Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units > > # Server, Default > MessageDigests.digest sha256 64 SUN thrpt 5 8564.689 ? 1459.552 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 1548.582 ? 78.888 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 110.800 ? 0.057 ops/ms > > # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics > MessageDigests.digest sha256 64 SUN thrpt 5 1471.399 ? 66.622 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 186.297 ? 0.127 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 12.448 ? 0.099 ops/ms > > # Server, -Xint > MessageDigests.digest sha256 64 SUN thrpt 5 27.046 ? 0.304 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 3.538 ? 0.060 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.238 ? 0.002 ops/ms > > # Zero > MessageDigests.digest sha256 64 SUN thrpt 5 26.696 ? 0.968 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 3.655 ? 0.024 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.241 ? 0.002 ops/ms > > Addtional testing: > - [x] `jdk/security` with Linux x86_64 server fastdebug > - [x] `jdk/security` with Linux x86_64 zero fastdebug Sounds impressive, I will take a look. Thanks! ------------- PR: https://git.openjdk.java.net/jdk/pull/1283 From hchao at openjdk.java.net Wed Nov 18 22:05:12 2020 From: hchao at openjdk.java.net (Hai-May Chao) Date: Wed, 18 Nov 2020 22:05:12 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR Message-ID: Small change to retrieve the raw bytes of manifest during verifying signed JAR. ------------- Commit messages: - 8253299: Manifest bytes are read twice when verifying a signed JAR Changes: https://git.openjdk.java.net/jdk/pull/1299/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1299&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8253299 Stats: 6 lines in 1 file changed: 5 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/1299.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1299/head:pull/1299 PR: https://git.openjdk.java.net/jdk/pull/1299 From forax at univ-mlv.fr Tue Nov 17 23:18:16 2020 From: forax at univ-mlv.fr (Remi Forax) Date: Wed, 18 Nov 2020 00:18:16 +0100 (CET) Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> Message-ID: <676865722.1878668.1605655096153.JavaMail.zimbra@u-pem.fr> An honest question, why do we need so many interfaces for the different categories of RandomGenerator ? My fear is that we are encoding the state of our knowledge of the different kinds of random generators now so it will not be pretty in the future when new categories of random generator are discovered/invented. If we can take example of the past to predict the future, 20 years ago, what should have been the hierarchy at that time. Is it not reasonable to think that we will need new kinds of random generator in the future ? I wonder if it's not better to have one interface and several optional methods like we have with the collections, it means that we are loosing the possibilities to precisely type a method that only works with a precise type of generator but it will be more future proof. R?mi ----- Mail original ----- > De: "Jim Laskey" > ?: "build-dev" , "core-libs-dev" , > security-dev at openjdk.java.net > Envoy?: Mardi 17 Novembre 2020 23:21:18 > Objet: Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] >> This PR is to introduce a new random number API for the JDK. The primary API is >> found in RandomGenerator and RandomGeneratorFactory. Further description can be >> found in the JEP https://openjdk.java.net/jeps/356 . > > Jim Laskey has updated the pull request with a new target base due to a merge or > a rebase. The pull request now contains 40 commits: > > - Merge branch 'master' into 8248862 > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Update package-info.java > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Updated RandomGeneratorFactory javadoc. > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Updated documentation for RandomGeneratorFactory. > - Merge branch 'master' into 8248862 > - Merge branch 'master' into 8248862 > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Move RandomGeneratorProperty > - Merge branch 'master' into 8248862 > - 8248862: Implement Enhanced Pseudo-Random Number Generators > > Clear up javadoc > - 8248862; Implement Enhanced Pseudo-Random Number Generators > > remove RandomGeneratorProperty from API > - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 > > ------------- > > Changes: https://git.openjdk.java.net/jdk/pull/1273/files > Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1273&range=02 > Stats: 14891 lines in 31 files changed: 11110 ins; 3704 del; 77 mod > Patch: https://git.openjdk.java.net/jdk/pull/1273.diff > Fetch: git fetch https://git.openjdk.java.net/jdk pull/1273/head:pull/1273 > > PR: https://git.openjdk.java.net/jdk/pull/1273 From redestad at openjdk.java.net Thu Nov 19 00:12:04 2020 From: redestad at openjdk.java.net (Claes Redestad) Date: Thu, 19 Nov 2020 00:12:04 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 21:59:01 GMT, Hai-May Chao wrote: > Small change to retrieve the raw bytes of manifest during verifying signed JAR. This seems like a good optimization. I think comparing the manifest name case insensitively might be preferable - e.g. using String.equalsIgnoreCase - but if the worst that can happen is that a non-conventionally cased is read twice then I think what you have here is good. ------------- Marked as reviewed by redestad (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/1299 From lancea at openjdk.java.net Thu Nov 19 01:25:04 2020 From: lancea at openjdk.java.net (Lance Andersen) Date: Thu, 19 Nov 2020 01:25:04 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: <6vja1mKMTZeMwBvOj8JPIUY7CzUKl-xzVx35_6Bp84Y=.55639475-6a09-4dc4-8cc5-03c72b874fc7@github.com> On Wed, 18 Nov 2020 21:59:01 GMT, Hai-May Chao wrote: > Small change to retrieve the raw bytes of manifest during verifying signed JAR. The changes looks good. I am assuming that we do not need an additional test for this and if so, please add a noreg label such as noreg-trivial to the bug ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From shade at openjdk.java.net Thu Nov 19 08:02:07 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Thu, 19 Nov 2020 08:02:07 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 [v2] In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 18:53:21 GMT, Weijun Wang wrote: >> This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). > > Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: > > not static anymore I like it, thanks. Minor nit follows. test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 46: > 44: public class PKCS12KeyStores { > 45: > 46: static char[] pass = "changeit".toCharArray(); This is still a bit weird: is it a constant? Then this should probably be: static final char[] PASS = "changeit".toCharArray(); ------------- Marked as reviewed by shade (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/1277 From weijun at openjdk.java.net Thu Nov 19 14:12:11 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Thu, 19 Nov 2020 14:12:11 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 [v2] In-Reply-To: References: Message-ID: On Thu, 19 Nov 2020 07:58:36 GMT, Aleksey Shipilev wrote: >> Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: >> >> not static anymore > > test/micro/org/openjdk/bench/java/security/PKCS12KeyStores.java line 46: > >> 44: public class PKCS12KeyStores { >> 45: >> 46: static char[] pass = "changeit".toCharArray(); > > This is still a bit weird: is it a constant? Then this should probably be: > static final char[] PASS = "changeit".toCharArray(); Yes, it should be. I'll include the change in the next push. Thanks for reviewing. ------------- PR: https://git.openjdk.java.net/jdk/pull/1277 From mullan at openjdk.java.net Thu Nov 19 14:19:09 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Thu, 19 Nov 2020 14:19:09 GMT Subject: Integrated: 8202343: Disable TLS 1.0 and 1.1 In-Reply-To: References: Message-ID: <2Npebmc0qi_SsT84qmfHelFPfo1oK2ySfX0zjGOuqug=.e9b03b97-6514-4308-a5ee-bbe3a9a55301@github.com> On Mon, 16 Nov 2020 20:18:16 GMT, Sean Mullan wrote: > This change disables the TLSv1 and TLSv1.1 protocols by adding them to the jdk.tls.disabledAlgorithms security property in the java.security file. These protocols use weak algorithms and are being deprecated by the IETF. They should be disabled by default to improve the default security configuration of the JDK. See the CSR for more rationale: https://bugs.openjdk.java.net/browse/JDK-8254713 > > The fix mostly involves changes to existing tests that for one reason or another depend on the TLSv1 and TLSv1.1 protocols being enabled. There is a new test specifically for this issue: test/jdk/sun/security/ssl/SSLContextImpl/SSLContextDefault.java This pull request has now been integrated. Changeset: 3a4b90f0 Author: Sean Mullan URL: https://git.openjdk.java.net/jdk/commit/3a4b90f0 Stats: 396 lines in 21 files changed: 273 ins; 97 del; 26 mod 8202343: Disable TLS 1.0 and 1.1 Reviewed-by: xuelei, dfuchs, coffeys ------------- PR: https://git.openjdk.java.net/jdk/pull/1235 From alanb at openjdk.java.net Thu Nov 19 17:11:03 2020 From: alanb at openjdk.java.net (Alan Bateman) Date: Thu, 19 Nov 2020 17:11:03 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: <5imglAfMavky8vzTpaXeov_LHVm_enaMB4zZaLmRbbU=.0241bc35-4f30-4323-be86-e12d7e6036d0@github.com> On Wed, 18 Nov 2020 21:59:01 GMT, Hai-May Chao wrote: > Small change to retrieve the raw bytes of manifest during verifying signed JAR. Marked as reviewed by alanb (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From lancea at openjdk.java.net Thu Nov 19 17:15:03 2020 From: lancea at openjdk.java.net (Lance Andersen) Date: Thu, 19 Nov 2020 17:15:03 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 21:59:01 GMT, Hai-May Chao wrote: > Small change to retrieve the raw bytes of manifest during verifying signed JAR. Marked as reviewed by lancea (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From lancea at openjdk.java.net Thu Nov 19 17:15:04 2020 From: lancea at openjdk.java.net (Lance Andersen) Date: Thu, 19 Nov 2020 17:15:04 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: <5imglAfMavky8vzTpaXeov_LHVm_enaMB4zZaLmRbbU=.0241bc35-4f30-4323-be86-e12d7e6036d0@github.com> References: <5imglAfMavky8vzTpaXeov_LHVm_enaMB4zZaLmRbbU=.0241bc35-4f30-4323-be86-e12d7e6036d0@github.com> Message-ID: On Thu, 19 Nov 2020 17:08:21 GMT, Alan Bateman wrote: >> Small change to retrieve the raw bytes of manifest during verifying signed JAR. > > Marked as reviewed by alanb (Reviewer). I can sponsor once you integrate ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From hchao at openjdk.java.net Thu Nov 19 17:27:04 2020 From: hchao at openjdk.java.net (Hai-May Chao) Date: Thu, 19 Nov 2020 17:27:04 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: On Thu, 19 Nov 2020 17:13:00 GMT, Lance Andersen wrote: >> Small change to retrieve the raw bytes of manifest during verifying signed JAR. > > Marked as reviewed by lancea (Reviewer). Thank you all for the review. I added the noreg-trivial label to the bug. ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From hchao at openjdk.java.net Thu Nov 19 17:27:04 2020 From: hchao at openjdk.java.net (Hai-May Chao) Date: Thu, 19 Nov 2020 17:27:04 GMT Subject: RFR: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: On Thu, 19 Nov 2020 17:20:58 GMT, Hai-May Chao wrote: >> Marked as reviewed by lancea (Reviewer). > > Thank you all for the review. I added the noreg-trivial label to the bug. Lance, I've entered /integrate. Thank you for sponsoring this! ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From hchao at openjdk.java.net Thu Nov 19 17:27:05 2020 From: hchao at openjdk.java.net (Hai-May Chao) Date: Thu, 19 Nov 2020 17:27:05 GMT Subject: Integrated: 8253299: Manifest bytes are read twice when verifying a signed JAR In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 21:59:01 GMT, Hai-May Chao wrote: > Small change to retrieve the raw bytes of manifest during verifying signed JAR. This pull request has now been integrated. Changeset: 9bb82232 Author: Hai-May Chao Committer: Lance Andersen URL: https://git.openjdk.java.net/jdk/commit/9bb82232 Stats: 6 lines in 1 file changed: 5 ins; 0 del; 1 mod 8253299: Manifest bytes are read twice when verifying a signed JAR Reviewed-by: redestad, lancea, alanb ------------- PR: https://git.openjdk.java.net/jdk/pull/1299 From jnimeh at openjdk.java.net Thu Nov 19 17:48:34 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Thu, 19 Nov 2020 17:48:34 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: > Hello all, > This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: - Update test to account for JDK-8202343 fix - Merge - Merge - Applied code review comments to tests - Fix cut/paste error with ECDH-RSA key exchange - Merge - Initial EdDSA/TLS solution ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1197/files - new: https://git.openjdk.java.net/jdk/pull/1197/files/59aced35..dee70944 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=01-02 Stats: 6780 lines in 253 files changed: 3650 ins; 1976 del; 1154 mod Patch: https://git.openjdk.java.net/jdk/pull/1197.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1197/head:pull/1197 PR: https://git.openjdk.java.net/jdk/pull/1197 From mullan at openjdk.java.net Thu Nov 19 18:54:12 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Thu, 19 Nov 2020 18:54:12 GMT Subject: RFR: JDK-8256682: JDK-8202343 is incomplete Message-ID: The fix for disabling TLS 1.0 and 1.1 is causing intermittent failures of this test which depends on TLSv1 and v1.1. This test needs to run its own VM because it now needs to modify a security property to re-enable TLSv1 and v1.1. ------------- Commit messages: - JDK-8256682: JDK-8202343 is incomplete Changes: https://git.openjdk.java.net/jdk/pull/1327/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1327&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256682 Stats: 4 lines in 1 file changed: 0 ins; 0 del; 4 mod Patch: https://git.openjdk.java.net/jdk/pull/1327.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1327/head:pull/1327 PR: https://git.openjdk.java.net/jdk/pull/1327 From dfuchs at openjdk.java.net Thu Nov 19 18:59:06 2020 From: dfuchs at openjdk.java.net (Daniel Fuchs) Date: Thu, 19 Nov 2020 18:59:06 GMT Subject: RFR: JDK-8256682: JDK-8202343 is incomplete In-Reply-To: References: Message-ID: On Thu, 19 Nov 2020 18:49:07 GMT, Sean Mullan wrote: > The fix for disabling TLS 1.0 and 1.1 is causing intermittent failures of this test which depends on TLSv1 and v1.1. This test needs to run its own VM because it now needs to modify a security property to re-enable TLSv1 and v1.1. Marked as reviewed by dfuchs (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1327 From mullan at openjdk.java.net Thu Nov 19 19:14:03 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Thu, 19 Nov 2020 19:14:03 GMT Subject: Integrated: JDK-8256682: JDK-8202343 is incomplete In-Reply-To: References: Message-ID: On Thu, 19 Nov 2020 18:49:07 GMT, Sean Mullan wrote: > The fix for disabling TLS 1.0 and 1.1 is causing intermittent failures of this test which depends on TLSv1 and v1.1. This test needs to run its own VM because it now needs to modify a security property to re-enable TLSv1 and v1.1. This pull request has now been integrated. Changeset: b9db002f Author: Sean Mullan URL: https://git.openjdk.java.net/jdk/commit/b9db002f Stats: 4 lines in 1 file changed: 0 ins; 0 del; 4 mod 8256682: JDK-8202343 is incomplete Reviewed-by: dfuchs ------------- PR: https://git.openjdk.java.net/jdk/pull/1327 From valeriep at openjdk.java.net Thu Nov 19 21:39:14 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Thu, 19 Nov 2020 21:39:14 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 05:14:11 GMT, Anthony Scarpino wrote: >> src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java line 560: >> >>> 558: System.arraycopy(buffer, 0, block, 0, blockSize); >>> 559: buflen -= block.length; >>> 560: return 0; >> >> Will bufLen > blockSize? Judging from the context of this method, buffer.length should always <= blockSize and never be larger? If bufLen == blockSize, perhaps we can just use buffer directly and no need to copy. > > This method is being removed Ok. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Thu Nov 19 21:39:15 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Thu, 19 Nov 2020 21:39:15 GMT Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v4] In-Reply-To: <1Goe8AGkytjQmXHg4xSkxj7WtKWoIXlJUvUsVJQIB8k=.cce1b9d5-26f0-46de-b095-9d3230ac4714@github.com> References: <1Goe8AGkytjQmXHg4xSkxj7WtKWoIXlJUvUsVJQIB8k=.cce1b9d5-26f0-46de-b095-9d3230ac4714@github.com> Message-ID: On Wed, 18 Nov 2020 04:28:38 GMT, Anthony Scarpino wrote: >> The current impl of constructBlock() seems to have code handling ibuffer >= blocksize scenario. Could you fix that and also pass the input offset into constructBlock() for this RFE? > > I redid the whole code Sure, I will be waiting for the next commit then. ------------- PR: https://git.openjdk.java.net/jdk/pull/411 From valeriep at openjdk.java.net Fri Nov 20 00:18:05 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 20 Nov 2020 00:18:05 GMT Subject: RFR: 8256523: Streamline Java SHA2 implementation In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 08:29:49 GMT, Aleksey Shipilev wrote: > Current `sun/security/provider/SHA2` implementation is written with lots of small method invocations on the fastpath in `implCompress0`. Normally it does not matter much, because compilers are able to inline through it, and then some compilers even intrinsify the entire `implCompress0`. > > But it comes as major downside for platforms that do not have SHA2 intrinsics, or those VM configs that blindly interpret the bytecode. Zero, for example, keeps re-entering the small methods when computing SHA2 digests during jmod/jlink generation during the build, and spends significant time there. Linux x86_64 Zero fastdebug builds **improve from 18.5 minutes to 11.0 minutes** with this change, which is a major win for development experience. > > Note that SHA1 is already written in similar streamlined style. SHA5 is written with helper functions. This patch moves SHA2 to be closer to SHA1 style-wise. > > Performance improvement in interpreted modes is substantial, about 4x..5x, while compiler modes are not affected. As measured by: `make test TEST="micro:MessageDigests" MICRO="FORK=1;ITER=5;WARMUP_ITER=5;WARMUP_TIME=1s;TIME=1s;OPTIONS=-p digesterName=sha256 -p provider=SUN"` > > Before: > > Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units > > # Server, Default > MessageDigests.digest sha256 64 SUN thrpt 5 8585.532 ? 219.896 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 1545.994 ? 73.325 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 110.550 ? 1.576 ops/ms > > # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics > MessageDigests.digest sha256 64 SUN thrpt 5 1426.117 ? 48.320 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 188.779 ? 0.097 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 12.512 ? 1.371 ops/ms > > # Server, -Xint > MessageDigests.digest sha256 64 SUN thrpt 5 6.143 ? 0.126 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 0.769 ? 0.008 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.051 ? 0.001 ops/ms > > # Zero > MessageDigests.digest sha256 64 SUN thrpt 5 5.358 ? 0.664 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 0.686 ? 0.003 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.046 ? 0.001 ops/ms > > After: > > Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units > > # Server, Default > MessageDigests.digest sha256 64 SUN thrpt 5 8564.689 ? 1459.552 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 1548.582 ? 78.888 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 110.800 ? 0.057 ops/ms > > # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics > MessageDigests.digest sha256 64 SUN thrpt 5 1471.399 ? 66.622 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 186.297 ? 0.127 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 12.448 ? 0.099 ops/ms > > # Server, -Xint > MessageDigests.digest sha256 64 SUN thrpt 5 27.046 ? 0.304 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 3.538 ? 0.060 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.238 ? 0.002 ops/ms > > # Zero > MessageDigests.digest sha256 64 SUN thrpt 5 26.696 ? 0.968 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 3.655 ? 0.024 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.241 ? 0.002 ops/ms > > Addtional testing: > - [x] `jdk/security` with Linux x86_64 server fastdebug > - [x] `jdk/security` with Linux x86_64 zero fastdebug Changes look good. ------------- Marked as reviewed by valeriep (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/1283 From shade at openjdk.java.net Fri Nov 20 06:49:02 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Fri, 20 Nov 2020 06:49:02 GMT Subject: RFR: 8256523: Streamline Java SHA2 implementation In-Reply-To: References: Message-ID: On Fri, 20 Nov 2020 00:14:55 GMT, Valerie Peng wrote: >> Current `sun/security/provider/SHA2` implementation is written with lots of small method invocations on the fastpath in `implCompress0`. Normally it does not matter much, because compilers are able to inline through it, and then some compilers even intrinsify the entire `implCompress0`. >> >> But it comes as major downside for platforms that do not have SHA2 intrinsics, or those VM configs that blindly interpret the bytecode. Zero, for example, keeps re-entering the small methods when computing SHA2 digests during jmod/jlink generation during the build, and spends significant time there. Linux x86_64 Zero fastdebug builds **improve from 18.5 minutes to 11.0 minutes** with this change, which is a major win for development experience. >> >> Note that SHA1 is already written in similar streamlined style. SHA5 is written with helper functions. This patch moves SHA2 to be closer to SHA1 style-wise. >> >> Performance improvement in interpreted modes is substantial, about 4x..5x, while compiler modes are not affected. As measured by: `make test TEST="micro:MessageDigests" MICRO="FORK=1;ITER=5;WARMUP_ITER=5;WARMUP_TIME=1s;TIME=1s;OPTIONS=-p digesterName=sha256 -p provider=SUN"` >> >> Before: >> >> Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units >> >> # Server, Default >> MessageDigests.digest sha256 64 SUN thrpt 5 8585.532 ? 219.896 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 1545.994 ? 73.325 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 110.550 ? 1.576 ops/ms >> >> # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics >> MessageDigests.digest sha256 64 SUN thrpt 5 1426.117 ? 48.320 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 188.779 ? 0.097 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 12.512 ? 1.371 ops/ms >> >> # Server, -Xint >> MessageDigests.digest sha256 64 SUN thrpt 5 6.143 ? 0.126 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 0.769 ? 0.008 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 0.051 ? 0.001 ops/ms >> >> # Zero >> MessageDigests.digest sha256 64 SUN thrpt 5 5.358 ? 0.664 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 0.686 ? 0.003 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 0.046 ? 0.001 ops/ms >> >> After: >> >> Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units >> >> # Server, Default >> MessageDigests.digest sha256 64 SUN thrpt 5 8564.689 ? 1459.552 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 1548.582 ? 78.888 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 110.800 ? 0.057 ops/ms >> >> # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics >> MessageDigests.digest sha256 64 SUN thrpt 5 1471.399 ? 66.622 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 186.297 ? 0.127 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 12.448 ? 0.099 ops/ms >> >> # Server, -Xint >> MessageDigests.digest sha256 64 SUN thrpt 5 27.046 ? 0.304 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 3.538 ? 0.060 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 0.238 ? 0.002 ops/ms >> >> # Zero >> MessageDigests.digest sha256 64 SUN thrpt 5 26.696 ? 0.968 ops/ms >> MessageDigests.digest sha256 1024 SUN thrpt 5 3.655 ? 0.024 ops/ms >> MessageDigests.digest sha256 16384 SUN thrpt 5 0.241 ? 0.002 ops/ms >> >> Addtional testing: >> - [x] `jdk/security` with Linux x86_64 server fastdebug >> - [x] `jdk/security` with Linux x86_64 zero fastdebug > > Changes look good. Thank you, @valeriepeng. I am not sure what is the review policy for this code, should I wait for another reviewer? ------------- PR: https://git.openjdk.java.net/jdk/pull/1283 From sean.coffey at oracle.com Fri Nov 20 11:32:40 2020 From: sean.coffey at oracle.com (=?UTF-8?Q?Se=c3=a1n_Coffey?=) Date: Fri, 20 Nov 2020 11:32:40 +0000 Subject: RFR: 8253368: TLS connection always receives close_notify exception In-Reply-To: References: <3b1dd501-f6c0-13d9-9e5b-13732e06c385@oracle.com> Message-ID: <3403c7d1-ecae-2a95-2a19-a06fde2666cc@oracle.com> On 13/11/2020 21:23, David Lloyd wrote: > Thinking about this some more, I suppose I tend to interpret the > shutdownInput() API as indicating that the caller doesn't really care > about any further data being received on the socket. I expect that a > truncation attack would only be significant if the socket EOF was > received before close_notify while the caller is trying to read data > from the socket. So in that light the change is probably OK (since it > only exists when explicitly shutting down the input) from the > perspective that I was thinking of. Whether it has any protocol-level > implications I don't know and won't comment on. > > That said, maybe shutdownInput(boolean) should be collapsed into > shutdownInput() since the parameter is no longer used? Thanks for the comments. Fair point on the method overload. One I'll look into. I'm looking to further study the consequences of the overall change some more and will reach out to other engineers for opinion also. Hope to revert to the list with an update in next 1-2 weeks. regards, Sean. > > On Fri, Nov 13, 2020 at 3:01 PM Se?n Coffey wrote: >> Open to discussion on that. It's also highlighted in the TLSv1.3 RFC. >> >> The TLS spec doesn't require a fatal alert to be issued when closing >> inbound without receiving the peer's close_notify. I've seen a handful >> of applications making JDK upgrades which are seeing regression as a >> result of this new JDK check (like the one described in this bug). If >> we're to keep the check in the JDK, should we restrict it to the v1.3 >> protocol or should we implement it based on a system property perhaps ? >> >> regards, >> Sean. >> >> On 13/11/2020 17:11, David Lloyd wrote: >>> How would a truncation attack be avoided in this case? >>> >>> On Fri, Nov 13, 2020 at 8:23 AM Sean Coffey wrote: >>>> removing the "closing inbound before receiving peer's close_notify" exception that can be seen with TLS stack if calling close on inbound. After reading the relevant parts of the TLS v1.2/v1.3 RFCs, I believe the local end point doesn't have to wait for close_notify alert from remote end. >>>> >>>> ------------- >>>> >>>> Commit messages: >>>> - 8253368: TLS connection always receives close_notify exception >>>> >>>> Changes: https://git.openjdk.java.net/jdk/pull/1205/files >>>> Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1205&range=00 >>>> Issue: https://bugs.openjdk.java.net/browse/JDK-8253368 >>>> Stats: 25 lines in 2 files changed: 12 ins; 10 del; 3 mod >>>> Patch: https://git.openjdk.java.net/jdk/pull/1205.diff >>>> Fetch: git fetch https://git.openjdk.java.net/jdk pull/1205/head:pull/1205 >>>> >>>> PR: https://git.openjdk.java.net/jdk/pull/1205 >>>> > From vlivanov at openjdk.java.net Fri Nov 20 15:00:18 2020 From: vlivanov at openjdk.java.net (Vladimir Ivanov) Date: Fri, 20 Nov 2020 15:00:18 GMT Subject: RFR: 8254231: Implementation of Foreign Linker API (Incubator) [v28] In-Reply-To: References: Message-ID: On Tue, 17 Nov 2020 11:49:26 GMT, Maurizio Cimadamore wrote: >> This patch contains the changes associated with the first incubation round of the foreign linker access API incubation >> (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). >> >> The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. >> >> Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. >> >> A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). >> >> Thanks >> Maurizio >> >> Webrev: >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev >> >> Javadoc: >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html >> >> Specdiff (relative to [3]): >> >> http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html >> >> CSR: >> >> https://bugs.openjdk.java.net/browse/JDK-8254232 >> >> >> >> ### API Changes >> >> The API changes are actually rather slim: >> >> * `LibraryLookup` >> * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. >> * `FunctionDescriptor` >> * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. >> * `CLinker` >> * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. >> * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. >> * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. >> * `NativeScope` >> * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. >> * `MemorySegment` >> * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. >> >> ### Safety >> >> The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). >> >> ### Implementation changes >> >> The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). >> >> As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. >> >> Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. >> >> The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. >> >> This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. >> >> For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. >> >> A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. >> >> At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: >> >> * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. >> >> * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). >> >> * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. >> >> For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). >> >> Again, for more readings on the internals of the foreign linker support, please refer to [5]. >> >> #### Test changes >> >> Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. >> >> Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. >> >> [1] - https://openjdk.java.net/jeps/389 >> [2] - https://openjdk.java.net/jeps/393 >> [3] - https://git.openjdk.java.net/jdk/pull/548 >> [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md >> [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html > > Maurizio Cimadamore has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 95 commits: > > - Merge branch 'master' into 8254231_linker > - Add `final` modifier on NativeLibraries.defaultLookup > - Fix aarch64 test failure > - Fix signature mismatch on aarch64 > - Merge pull request #9 from JornVernee/Windows_Warnings > > Fix warnings on MSVC > - Fix warnings on MSVC > - Merge pull request #8 from JornVernee/Vlad_Comments > > Address More Review comments > - - Don't print anything in nmehtod debug output for native invoker if there are none. > - Use memcpy to copy native stubs to nmethod data > - Simplify print code > - Merge branch '8254231_linker' into Vlad_Comments > - ... and 85 more: https://git.openjdk.java.net/jdk/compare/a7422ac2...40bd5df1 Compiler changes look good. ------------- Marked as reviewed by vlivanov (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/634 From xuelei at openjdk.java.net Fri Nov 20 19:36:10 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Fri, 20 Nov 2020 19:36:10 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Thu, 19 Nov 2020 17:48:34 GMT, Jamil Nimeh wrote: >> Hello all, >> This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. > > Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: > > - Update test to account for JDK-8202343 fix > - Merge > - Merge > - Applied code review comments to tests > - Fix cut/paste error with ECDH-RSA key exchange > - Merge > - Initial EdDSA/TLS solution src/java.base/share/classes/sun/security/ssl/CertificateRequest.java line 83: > 81: ECDSA_SIGN ((byte)0x40, "ecdsa_sign", > 82: List.of("EC", "EdDSA"), > 83: JsseJce.isEcAvailable()), Would you like to add RFC 8422 to the comment line as well? src/java.base/share/classes/sun/security/ssl/JsseJce.java line 97: > 95: */ > 96: static final String SIGNATURE_EDDSA = "EdDSA"; > 97: Please update the copyright year. Is it possible that "ed25519" or "ed448" is used as the signature algorithm, especially in the X.509 certificate implementation? src/java.base/share/classes/sun/security/ssl/SignatureScheme.java line 73: > 71: ED448 (0x0808, "ed448", "Ed448", > 72: "EdDSA", > 73: ProtocolVersion.PROTOCOLS_12_13), You may also want to check if EdDSA is available in the following block: - 282 if ("EC".equals(keyAlgorithm)) { + 282 if ("EC".equals(keyAlgorithm) || "EdDSA"... ) { 283 mediator = JsseJce.isEcAvailable(); 284 } src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java line 48: > 46: if (authentication != null) { > 47: this.authentication = new ArrayList<>(); > 48: this.authentication.addAll(authentication); I may use an immutable list, for example List.copyOf(authentication). src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java line 134: > 132: SSLAuthentication authType = li.next(); > 133: auHandshakes = authType.getRelatedHandshakers(handshakeContext); > 134: } I guess for-each loop could be a little bit more lightweight. src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java line 163: > 161: SSLAuthentication authType = li.next(); > 162: auProducers = authType.getHandshakeProducers(handshakeContext); > 163: } Use for-each? ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From weijun at openjdk.java.net Fri Nov 20 19:56:23 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 20 Nov 2020 19:56:23 GMT Subject: RFR: 8256507: Add a micro benchmark for JDK-8153005 [v3] In-Reply-To: References: Message-ID: > This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). Weijun Wang has updated the pull request incrementally with one additional commit since the last revision: private fields, comments, new and old in methods names ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1277/files - new: https://git.openjdk.java.net/jdk/pull/1277/files/9247081d..72265960 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1277&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1277&range=01-02 Stats: 88 lines in 1 file changed: 46 ins; 31 del; 11 mod Patch: https://git.openjdk.java.net/jdk/pull/1277.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1277/head:pull/1277 PR: https://git.openjdk.java.net/jdk/pull/1277 From weijun at openjdk.java.net Fri Nov 20 19:56:25 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 20 Nov 2020 19:56:25 GMT Subject: Integrated: 8256507: Add a micro benchmark for JDK-8153005 In-Reply-To: References: Message-ID: On Tue, 17 Nov 2020 21:46:38 GMT, Weijun Wang wrote: > This is a micro benchmark for various algorithm settings of PKCS keystores. Strong for new algorithms and weak for old ones. Different iteration counts are tried. The result should show that the current setting (strong10000) is more efficient than old setting (weak50000). This pull request has now been integrated. Changeset: b21b96df Author: Weijun Wang URL: https://git.openjdk.java.net/jdk/commit/b21b96df Stats: 186 lines in 1 file changed: 186 ins; 0 del; 0 mod 8256507: Add a micro benchmark for JDK-8153005 Reviewed-by: shade ------------- PR: https://git.openjdk.java.net/jdk/pull/1277 From valeriep at openjdk.java.net Fri Nov 20 20:08:03 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Fri, 20 Nov 2020 20:08:03 GMT Subject: RFR: 8256523: Streamline Java SHA2 implementation In-Reply-To: References: Message-ID: <2UNnY52uunvd2XO0YU6JvhwFJAuXvGcT04qMSo0ajvg=.592500a5-bf80-49d8-a6a1-38a97261cc2a@github.com> On Fri, 20 Nov 2020 06:46:09 GMT, Aleksey Shipilev wrote: >> Changes look good. > > Thank you, @valeriepeng. I am not sure what is the review policy for this code, should I wait for another reviewer? One reviewer is good enough. You can go ahead and integrate. Thanks~ ------------- PR: https://git.openjdk.java.net/jdk/pull/1283 From weijun at openjdk.java.net Fri Nov 20 20:11:08 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 20 Nov 2020 20:11:08 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Thu, 19 Nov 2020 17:48:34 GMT, Jamil Nimeh wrote: >> Hello all, >> This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. > > Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: > > - Update test to account for JDK-8202343 fix > - Merge > - Merge > - Applied code review comments to tests > - Fix cut/paste error with ECDH-RSA key exchange > - Merge > - Initial EdDSA/TLS solution src/java.base/share/classes/sun/security/ssl/CertificateRequest.java line 139: > 137: if (cct.isAvailable) { > 138: cct.keyAlgorithm.forEach(key -> { > 139: if (!keyTypes.contains(key)) { Can this ever happen? Why not just `addAll`? ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From weijun at openjdk.java.net Fri Nov 20 20:11:11 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 20 Nov 2020 20:11:11 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 18:09:26 GMT, Xue-Lei Andrew Fan wrote: >> Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: >> >> - Update test to account for JDK-8202343 fix >> - Merge >> - Merge >> - Applied code review comments to tests >> - Fix cut/paste error with ECDH-RSA key exchange >> - Merge >> - Initial EdDSA/TLS solution > > src/java.base/share/classes/sun/security/ssl/JsseJce.java line 97: > >> 95: */ >> 96: static final String SIGNATURE_EDDSA = "EdDSA"; >> 97: > > Please update the copyright year. > > Is it possible that "ed25519" or "ed448" is used as the signature algorithm, especially in the X.509 certificate implementation? SunEC's algorithm name for keys are always "EdDSA", but I know BC returns "Ed25519" or "Ed448". ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Fri Nov 20 20:11:15 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Fri, 20 Nov 2020 20:11:15 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 17:31:20 GMT, Xue-Lei Andrew Fan wrote: >> Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: >> >> - Update test to account for JDK-8202343 fix >> - Merge >> - Merge >> - Applied code review comments to tests >> - Fix cut/paste error with ECDH-RSA key exchange >> - Merge >> - Initial EdDSA/TLS solution > > src/java.base/share/classes/sun/security/ssl/CertificateRequest.java line 83: > >> 81: ECDSA_SIGN ((byte)0x40, "ecdsa_sign", >> 82: List.of("EC", "EdDSA"), >> 83: JsseJce.isEcAvailable()), > > Would you like to add RFC 8422 to the comment line as well? I think that's a good idea. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Fri Nov 20 20:21:07 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Fri, 20 Nov 2020 20:21:07 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 18:37:36 GMT, Xue-Lei Andrew Fan wrote: >> Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: >> >> - Update test to account for JDK-8202343 fix >> - Merge >> - Merge >> - Applied code review comments to tests >> - Fix cut/paste error with ECDH-RSA key exchange >> - Merge >> - Initial EdDSA/TLS solution > > src/java.base/share/classes/sun/security/ssl/SignatureScheme.java line 73: > >> 71: ED448 (0x0808, "ed448", "Ed448", >> 72: "EdDSA", >> 73: ProtocolVersion.PROTOCOLS_12_13), > > You may also want to check if EdDSA is available in the following block: > - 282 if ("EC".equals(keyAlgorithm)) { > + 282 if ("EC".equals(keyAlgorithm) || "EdDSA"... ) { > 283 mediator = JsseJce.isEcAvailable(); > 284 } JsseJce.isEcAvailable doesn't check for EdDSA availability so I'm not sure we want that second clause. I don't think the EdDSA code is implemented in the same module as the other EC code is so I don't know if we'd want to extend isEcAvailable to include EdDSA. I'll need to go look to see where EdDSA is located relative to the EC code. > src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java line 48: > >> 46: if (authentication != null) { >> 47: this.authentication = new ArrayList<>(); >> 48: this.authentication.addAll(authentication); > > I may use an immutable list, for example List.copyOf(authentication). That's probably a good idea. It doesn't look like we're making changes to the List outside of the constructor. > src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java line 134: > >> 132: SSLAuthentication authType = li.next(); >> 133: auHandshakes = authType.getRelatedHandshakers(handshakeContext); >> 134: } > > I guess for-each loop could be a little bit more lightweight. Yeah, I thought about that. I just like having all the loop termination clauses in one place rather than testing in the loop body and breaking. I can change it to for-each though, no strong feelings one way or the other. > src/java.base/share/classes/sun/security/ssl/SSLKeyExchange.java line 163: > >> 161: SSLAuthentication authType = li.next(); >> 162: auProducers = authType.getHandshakeProducers(handshakeContext); >> 163: } > > Use for-each? Will change to for-each. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Fri Nov 20 20:25:07 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Fri, 20 Nov 2020 20:25:07 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 19:58:23 GMT, Weijun Wang wrote: >> Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision: >> >> - Update test to account for JDK-8202343 fix >> - Merge >> - Merge >> - Applied code review comments to tests >> - Fix cut/paste error with ECDH-RSA key exchange >> - Merge >> - Initial EdDSA/TLS solution > > src/java.base/share/classes/sun/security/ssl/CertificateRequest.java line 139: > >> 137: if (cct.isAvailable) { >> 138: cct.keyAlgorithm.forEach(key -> { >> 139: if (!keyTypes.contains(key)) { > > Can this ever happen? Why not just `addAll`? I wanted to make sure we didn't end up with duplicates if two different certificate types had the same underlying key type and also to deal with both well-formed certificate request messages or ones that erroneously reiterate the type. It is definitely an edge case. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From xuelei at openjdk.java.net Fri Nov 20 20:43:06 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Fri, 20 Nov 2020 20:43:06 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 20:12:47 GMT, Jamil Nimeh wrote: >> src/java.base/share/classes/sun/security/ssl/SignatureScheme.java line 73: >> >>> 71: ED448 (0x0808, "ed448", "Ed448", >>> 72: "EdDSA", >>> 73: ProtocolVersion.PROTOCOLS_12_13), >> >> You may also want to check if EdDSA is available in the following block: >> - 282 if ("EC".equals(keyAlgorithm)) { >> + 282 if ("EC".equals(keyAlgorithm) || "EdDSA"... ) { >> 283 mediator = JsseJce.isEcAvailable(); >> 284 } > > JsseJce.isEcAvailable doesn't check for EdDSA availability so I'm not sure we want that second clause. I don't think the EdDSA code is implemented in the same module as the other EC code is so I don't know if we'd want to extend isEcAvailable to include EdDSA. I'll need to go look to see where EdDSA is located relative to the EC code. Hm, maybe a new isEdDsaAvailable(). ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From github.com+1472572+rogermb at openjdk.java.net Fri Nov 20 23:44:04 2020 From: github.com+1472572+rogermb at openjdk.java.net (Roger Baumgartner) Date: Fri, 20 Nov 2020 23:44:04 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 13:45:12 GMT, Jim Laskey wrote: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html > > old PR: https://github.com/openjdk/jdk/pull/1273 src/java.base/share/classes/java/util/random/package-info.java line 149: > 147: * > 148: *

For an application running in a 32-bit hardware environment and using > 149: * only one thread or a small number of threads, may be a good choice. I think the name of the suitable algorithm is missing here. ------------- PR: https://git.openjdk.java.net/jdk/pull/1292 From weijun at openjdk.java.net Sat Nov 21 02:03:12 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Sat, 21 Nov 2020 02:03:12 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 20:22:33 GMT, Jamil Nimeh wrote: >> src/java.base/share/classes/sun/security/ssl/CertificateRequest.java line 139: >> >>> 137: if (cct.isAvailable) { >>> 138: cct.keyAlgorithm.forEach(key -> { >>> 139: if (!keyTypes.contains(key)) { >> >> Can this ever happen? Why not just `addAll`? > > I wanted to make sure we didn't end up with duplicates if two different certificate types had the same underlying key type and also to deal with both well-formed certificate request messages or ones that erroneously reiterate the type. It is definitely an edge case. OK. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From jnimeh at openjdk.java.net Sat Nov 21 02:03:12 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Sat, 21 Nov 2020 02:03:12 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v3] In-Reply-To: References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: On Fri, 20 Nov 2020 20:39:46 GMT, Xue-Lei Andrew Fan wrote: >> JsseJce.isEcAvailable doesn't check for EdDSA availability so I'm not sure we want that second clause. I don't think the EdDSA code is implemented in the same module as the other EC code is so I don't know if we'd want to extend isEcAvailable to include EdDSA. I'll need to go look to see where EdDSA is located relative to the EC code. > > Hm, maybe a new isEdDsaAvailable(). The reasons for having isEcAvailable for EC keys do not apply for EdDSA. I don't think we should make any changes to this part of the code right now. ------------- PR: https://git.openjdk.java.net/jdk/pull/1197 From clanger at openjdk.java.net Sat Nov 21 23:24:47 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Sat, 21 Nov 2020 23:24:47 GMT Subject: RFR: 8256818: SSLSocket that is never bound or connected leaks socket resources In-Reply-To: References: Message-ID: On Sat, 21 Nov 2020 08:32:17 GMT, Christoph Langer wrote: > There is a flaw in sun.security.ssl.SSLSocketImpl::close() which leads to leaking socket resources after JDK-8224829. > > The close method calls duplexCloseOutput() and duplexCloseInput(). In case of an exception in any of these methods, the call to closeSocket() is bypassed, and the underlying Socket may not be closed. > > This manifests in a real life leak after JDK-8224829 has introduced a call to getSoLinger() on the path of duplexCloseOutput -> closeNotify. If socket impl / OS socket hadn't been created yet it is done at that place. But then after duplexCloseOutput eventually fails with a SocketException since the socket wasn't connected, closing fails to call Socket::close(). > > This problem can be reproduced by this code: > SSLSocket sslSocket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); > sslSocket.getSSLParameters(); > sslSocket.close(); > > This is what happens when SSLContext.getDefault().getDefaultSSLParameters() is called, with close() being eventually called by the finalizer. > > I'll open this PR as draft for now to start discussion. I'll create a testcase to reproduce the issue and add it soon. > > I propose to modify the close method such that duplexClose is only done on a connected/bound socket. Maybe it even suffices to only do it when connected. > > Secondly, I'm proposing to improve exception handling a bit. So in case there's an IOException on the path of duplexClose, it is caught and logged. But the real close moves to the finally block since it should be done unconditionally. I changed the check for when to do duplexClose to only do it when socket isConnected(). I also added a testcase which should work on all platforms. For windows I borrowed some functionality introduced lately with test java/lang/ProcessBuilder/checkHandles/CheckHandles.java which I moved to the test library for that reason. Now it's ready to review. ------------- PR: https://git.openjdk.java.net/jdk/pull/1363 From clanger at openjdk.java.net Sat Nov 21 23:24:47 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Sat, 21 Nov 2020 23:24:47 GMT Subject: RFR: 8256818: SSLSocket that is never bound or connected leaks socket resources Message-ID: There is a flaw in sun.security.ssl.SSLSocketImpl::close() which leads to leaking socket resources after JDK-8224829. The close method calls duplexCloseOutput() and duplexCloseInput(). In case of an exception in any of these methods, the call to closeSocket() is bypassed, and the underlying Socket may not be closed. This manifests in a real life leak after JDK-8224829 has introduced a call to getSoLinger() on the path of duplexCloseOutput -> closeNotify. If socket impl / OS socket hadn't been created yet it is done at that place. But then after duplexCloseOutput eventually fails with a SocketException since the socket wasn't connected, closing fails to call Socket::close(). This problem can be reproduced by this code: SSLSocket sslSocket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); sslSocket.getSSLParameters(); sslSocket.close(); This is what happens when SSLContext.getDefault().getDefaultSSLParameters() is called, with close() being eventually called by the finalizer. I'll open this PR as draft for now to start discussion. I'll create a testcase to reproduce the issue and add it soon. I propose to modify the close method such that duplexClose is only done on a connected/bound socket. Maybe it even suffices to only do it when connected. Secondly, I'm proposing to improve exception handling a bit. So in case there's an IOException on the path of duplexClose, it is caught and logged. But the real close moves to the finally block since it should be done unconditionally. ------------- Commit messages: - Add testcase for socket leak - Only duplexClose when socket isConnected() - 8256818: SSLSocket that is never bound or connected leaks socket resources Changes: https://git.openjdk.java.net/jdk/pull/1363/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1363&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8256818 Stats: 130 lines in 5 files changed: 98 ins; 15 del; 17 mod Patch: https://git.openjdk.java.net/jdk/pull/1363.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1363/head:pull/1363 PR: https://git.openjdk.java.net/jdk/pull/1363 From clanger at openjdk.java.net Sun Nov 22 10:45:44 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Sun, 22 Nov 2020 10:45:44 GMT Subject: RFR: 8256818: SSLSocket that is never bound or connected leaks socket resources [v2] In-Reply-To: References: Message-ID: > There is a flaw in sun.security.ssl.SSLSocketImpl::close() which leads to leaking socket resources after JDK-8224829. > > The close method calls duplexCloseOutput() and duplexCloseInput(). In case of an exception in any of these methods, the call to closeSocket() is bypassed, and the underlying Socket may not be closed. > > This manifests in a real life leak after JDK-8224829 has introduced a call to getSoLinger() on the path of duplexCloseOutput -> closeNotify. If socket impl / OS socket hadn't been created yet it is done at that place. But then after duplexCloseOutput eventually fails with a SocketException since the socket wasn't connected, closing fails to call Socket::close(). > > This problem can be reproduced by this code: > SSLSocket sslSocket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); > sslSocket.getSSLParameters(); > sslSocket.close(); > > This is what happens when SSLContext.getDefault().getDefaultSSLParameters() is called, with close() being eventually called by the finalizer. > > I'll open this PR as draft for now to start discussion. I'll create a testcase to reproduce the issue and add it soon. > > I propose to modify the close method such that duplexClose is only done on a connected/bound socket. Maybe it even suffices to only do it when connected. > > Secondly, I'm proposing to improve exception handling a bit. So in case there's an IOException on the path of duplexClose, it is caught and logged. But the real close moves to the finally block since it should be done unconditionally. Christoph Langer has updated the pull request incrementally with one additional commit since the last revision: Simplify the test ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1363/files - new: https://git.openjdk.java.net/jdk/pull/1363/files/c1663d93..34a1a218 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1363&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1363&range=00-01 Stats: 4 lines in 1 file changed: 0 ins; 3 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/1363.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1363/head:pull/1363 PR: https://git.openjdk.java.net/jdk/pull/1363 From shade at openjdk.java.net Sun Nov 22 18:05:35 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Sun, 22 Nov 2020 18:05:35 GMT Subject: RFR: 8256523: Streamline Java SHA2 implementation In-Reply-To: <2UNnY52uunvd2XO0YU6JvhwFJAuXvGcT04qMSo0ajvg=.592500a5-bf80-49d8-a6a1-38a97261cc2a@github.com> References: <2UNnY52uunvd2XO0YU6JvhwFJAuXvGcT04qMSo0ajvg=.592500a5-bf80-49d8-a6a1-38a97261cc2a@github.com> Message-ID: On Fri, 20 Nov 2020 20:05:19 GMT, Valerie Peng wrote: >> Thank you, @valeriepeng. I am not sure what is the review policy for this code, should I wait for another reviewer? > > One reviewer is good enough. You can go ahead and integrate. Thanks~ Got it, thanks! ------------- PR: https://git.openjdk.java.net/jdk/pull/1283 From shade at openjdk.java.net Sun Nov 22 18:05:36 2020 From: shade at openjdk.java.net (Aleksey Shipilev) Date: Sun, 22 Nov 2020 18:05:36 GMT Subject: Integrated: 8256523: Streamline Java SHA2 implementation In-Reply-To: References: Message-ID: On Wed, 18 Nov 2020 08:29:49 GMT, Aleksey Shipilev wrote: > Current `sun/security/provider/SHA2` implementation is written with lots of small method invocations on the fastpath in `implCompress0`. Normally it does not matter much, because compilers are able to inline through it, and then some compilers even intrinsify the entire `implCompress0`. > > But it comes as major downside for platforms that do not have SHA2 intrinsics, or those VM configs that blindly interpret the bytecode. Zero, for example, keeps re-entering the small methods when computing SHA2 digests during jmod/jlink generation during the build, and spends significant time there. Linux x86_64 Zero fastdebug builds **improve from 18.5 minutes to 11.0 minutes** with this change, which is a major win for development experience. > > Note that SHA1 is already written in similar streamlined style. SHA5 is written with helper functions. This patch moves SHA2 to be closer to SHA1 style-wise. > > Performance improvement in interpreted modes is substantial, about 4x..5x, while compiler modes are not affected. As measured by: `make test TEST="micro:MessageDigests" MICRO="FORK=1;ITER=5;WARMUP_ITER=5;WARMUP_TIME=1s;TIME=1s;OPTIONS=-p digesterName=sha256 -p provider=SUN"` > > Before: > > Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units > > # Server, Default > MessageDigests.digest sha256 64 SUN thrpt 5 8585.532 ? 219.896 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 1545.994 ? 73.325 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 110.550 ? 1.576 ops/ms > > # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics > MessageDigests.digest sha256 64 SUN thrpt 5 1426.117 ? 48.320 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 188.779 ? 0.097 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 12.512 ? 1.371 ops/ms > > # Server, -Xint > MessageDigests.digest sha256 64 SUN thrpt 5 6.143 ? 0.126 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 0.769 ? 0.008 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.051 ? 0.001 ops/ms > > # Zero > MessageDigests.digest sha256 64 SUN thrpt 5 5.358 ? 0.664 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 0.686 ? 0.003 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.046 ? 0.001 ops/ms > > After: > > Benchmark (digesterName) (length) (provider) Mode Cnt Score Error Units > > # Server, Default > MessageDigests.digest sha256 64 SUN thrpt 5 8564.689 ? 1459.552 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 1548.582 ? 78.888 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 110.800 ? 0.057 ops/ms > > # Server, -XX:+UnlockDiagnosticVMOptions -XX:-UseSHA256Intrinsics > MessageDigests.digest sha256 64 SUN thrpt 5 1471.399 ? 66.622 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 186.297 ? 0.127 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 12.448 ? 0.099 ops/ms > > # Server, -Xint > MessageDigests.digest sha256 64 SUN thrpt 5 27.046 ? 0.304 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 3.538 ? 0.060 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.238 ? 0.002 ops/ms > > # Zero > MessageDigests.digest sha256 64 SUN thrpt 5 26.696 ? 0.968 ops/ms > MessageDigests.digest sha256 1024 SUN thrpt 5 3.655 ? 0.024 ops/ms > MessageDigests.digest sha256 16384 SUN thrpt 5 0.241 ? 0.002 ops/ms > > Addtional testing: > - [x] `jdk/security` with Linux x86_64 server fastdebug > - [x] `jdk/security` with Linux x86_64 zero fastdebug This pull request has now been integrated. Changeset: d46f6f5a Author: Aleksey Shipilev URL: https://git.openjdk.java.net/jdk/commit/d46f6f5a Stats: 123 lines in 1 file changed: 41 ins; 78 del; 4 mod 8256523: Streamline Java SHA2 implementation Reviewed-by: valeriep ------------- PR: https://git.openjdk.java.net/jdk/pull/1283 From clanger at openjdk.java.net Sun Nov 22 18:27:56 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Sun, 22 Nov 2020 18:27:56 GMT Subject: RFR: 8256818: SSLSocket that is never bound or connected leaks socket resources [v3] In-Reply-To: References: Message-ID: <4_PBT9hcenuv1E6ksPKKd0K9jMLdWQNADguEHvOmdYk=.006c5b9f-ed94-4ad9-b4aa-f63de2b03dd9@github.com> > There is a flaw in sun.security.ssl.SSLSocketImpl::close() which leads to leaking socket resources after JDK-8224829. > > The close method calls duplexCloseOutput() and duplexCloseInput(). In case of an exception in any of these methods, the call to closeSocket() is bypassed, and the underlying Socket may not be closed. > > This manifests in a real life leak after JDK-8224829 has introduced a call to getSoLinger() on the path of duplexCloseOutput -> closeNotify. If socket impl / OS socket hadn't been created yet it is done at that place. But then after duplexCloseOutput eventually fails with a SocketException since the socket wasn't connected, closing fails to call Socket::close(). > > This problem can be reproduced by this code: > SSLSocket sslSocket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); > sslSocket.getSSLParameters(); > sslSocket.close(); > > This is what happens when SSLContext.getDefault().getDefaultSSLParameters() is called, with close() being eventually called by the finalizer. > > I'll open this PR as draft for now to start discussion. I'll create a testcase to reproduce the issue and add it soon. > > I propose to modify the close method such that duplexClose is only done on a connected/bound socket. Maybe it even suffices to only do it when connected. > > Secondly, I'm proposing to improve exception handling a bit. So in case there's an IOException on the path of duplexClose, it is caught and logged. But the real close moves to the finally block since it should be done unconditionally. Christoph Langer has updated the pull request incrementally with one additional commit since the last revision: Small test improvement ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1363/files - new: https://git.openjdk.java.net/jdk/pull/1363/files/34a1a218..e280436b Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1363&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1363&range=01-02 Stats: 3 lines in 1 file changed: 2 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/1363.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1363/head:pull/1363 PR: https://git.openjdk.java.net/jdk/pull/1363 From mcimadamore at openjdk.java.net Mon Nov 23 11:04:09 2020 From: mcimadamore at openjdk.java.net (Maurizio Cimadamore) Date: Mon, 23 Nov 2020 11:04:09 GMT Subject: Integrated: 8254231: Implementation of Foreign Linker API (Incubator) In-Reply-To: References: Message-ID: On Tue, 13 Oct 2020 13:08:14 GMT, Maurizio Cimadamore wrote: > This patch contains the changes associated with the first incubation round of the foreign linker access API incubation > (see JEP 389 [1]). This work is meant to sit on top of the foreign memory access support (see JEP 393 [2] and associated pull request [3]). > > The main goal of this API is to provide a way to call native functions from Java code without the need of intermediate JNI glue code. In order to do this, native calls are modeled through the MethodHandle API. I suggest reading the writeup [4] I put together few weeks ago, which illustrates what the foreign linker support is, and how it should be used by clients. > > Disclaimer: the pull request mechanism isn't great at managing *dependent* reviews. For this reasons, I'm attaching a webrev which contains only the differences between this PR and the memory access PR. I will be periodically uploading new webrevs, as new iterations come out, to try and make the life of reviewers as simple as possible. > > A big thank to Jorn Vernee and Vladimir Ivanov - they are the main architects of all the hotspot changes you see here, and without their help, the foreign linker support wouldn't be what it is today. As usual, a big thank to Paul Sandoz, who provided many insights (often by trying the bits first hand). > > Thanks > Maurizio > > Webrev: > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/webrev > > Javadoc: > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/javadoc/jdk/incubator/foreign/package-summary.html > > Specdiff (relative to [3]): > > http://cr.openjdk.java.net/~mcimadamore/8254231_v1/specdiff_delta/overview-summary.html > > CSR: > > https://bugs.openjdk.java.net/browse/JDK-8254232 > > > > ### API Changes > > The API changes are actually rather slim: > > * `LibraryLookup` > * This class allows clients to lookup symbols in native libraries; the interface is fairly simple; you can load a library by name, or absolute path, and then lookup symbols on that library. > * `FunctionDescriptor` > * This is an abstraction that is very similar, in spirit, to `MethodType`; it is, at its core, an aggregate of memory layouts for the function arguments/return type. A function descriptor is used to describe the signature of a native function. > * `CLinker` > * This is the real star of the show. A `CLinker` has two main methods: `downcallHandle` and `upcallStub`; the first takes a native symbol (as obtained from `LibraryLookup`), a `MethodType` and a `FunctionDescriptor` and returns a `MethodHandle` instance which can be used to call the target native symbol. The second takes an existing method handle, and a `FunctionDescriptor` and returns a new `MemorySegment` corresponding to a code stub allocated by the VM which acts as a trampoline from native code to the user-provided method handle. This is very useful for implementing upcalls. > * This class also contains the various layout constants that should be used by clients when describing native signatures (e.g. `C_LONG` and friends); these layouts contain additional ABI classfication information (in the form of layout attributes) which is used by the runtime to *infer* how Java arguments should be shuffled for the native call to take place. > * Finally, this class provides some helper functions e.g. so that clients can convert Java strings into C strings and back. > * `NativeScope` > * This is an helper class which allows clients to group together logically related allocations; that is, rather than allocating separate memory segments using separate *try-with-resource* constructs, a `NativeScope` allows clients to use a _single_ block, and allocate all the required segments there. This is not only an usability boost, but also a performance boost, since not all allocation requests will be turned into `malloc` calls. > * `MemorySegment` > * Only one method added here - namely `handoff(NativeScope)` which allows a segment to be transferred onto an existing native scope. > > ### Safety > > The foreign linker API is intrinsically unsafe; many things can go wrong when requesting a native method handle. For instance, the description of the native signature might be wrong (e.g. have too many arguments) - and the runtime has, in the general case, no way to detect such mismatches. For these reasons, obtaining a `CLinker` instance is a *restricted* operation, which can be enabled by specifying the usual JDK property `-Dforeign.restricted=permit` (as it's the case for other restricted method in the foreign memory API). > > ### Implementation changes > > The Java changes associated with `LibraryLookup` are relative straightforward; the only interesting thing to note here is that library loading does _not_ depend on class loaders, so `LibraryLookup` is not subject to the same restrictions which apply to JNI library loading (e.g. same library cannot be loaded by different classloaders). > > As for `NativeScope` the changes are again relatively straightforward; it is an API which sits neatly on top of the foreign meory access API, providing some kind of allocation service which shares the same underlying memory segment(s), and turns an allocation request into a segment slice, which is a much less expensive operation. `NativeScope` comes in two variants: there are native scopes for which the allocation size is known a priori, and native scopes which can grow - these two schemes are implemented by two separate subclasses of `AbstractNativeScopeImpl`. > > Of course the bulk of the changes are to support the `CLinker` downcall/upcall routines. These changes cut pretty deep into the JVM; I'll briefly summarize the goal of some of this changes - for further details, Jorn has put together a detailed writeup which explains the rationale behind the VM support, with some references to the code [5]. > > The main idea behind foreign linker is to infer, given a Java method type (expressed as a `MethodType` instance) and the description of the signature of a native function (expressed as a `FunctionDescriptor` instance) a _recipe_ that can be used to turn a Java call into the corresponding native call targeting the requested native function. > > This inference scheme can be defined in a pretty straightforward fashion by looking at the various ABI specifications (for instance, see [6] for the SysV ABI, which is the one used on Linux/Mac). The various `CallArranger` classes, of which we have a flavor for each supported platform, do exactly that kind of inference. > > For the inference process to work, we need to attach extra information to memory layouts; it is no longer sufficient to know e.g. that a layout is 32/64 bits - we need to know whether it is meant to represent a floating point value, or an integral value; this knowledge is required because floating points are passed in different registers by most ABIs. For this reason, `CLinker` offers a set of pre-baked, platform-dependent layout constants which contain the required classification attributes (e.g. a `Clinker.TypeKind` enum value). The runtime extracts this attribute, and performs classification accordingly. > > A native call is decomposed into a sequence of basic, primitive operations, called `Binding` (see the great javadoc on the `Binding.java` class for more info). There are many such bindings - for instance the `Move` binding is used to move a value into a specific machine register/stack slot. So, the main job of the various `CallingArranger` classes is to determine, given a Java `MethodType` and `FunctionDescriptor` what is the set of bindings associated with the downcall/upcall. > > At the heart of the foreign linker support is the `ProgrammableInvoker` class. This class effectively generates a `MethodHandle` which follows the steps described by the various bindings obtained by `CallArranger`. There are actually various strategies to interpret these bindings - listed below: > > * basic intepreted mode; in this mode, all bindings are interpreted using a stack-based machine written in Java (see `BindingInterpreter`), except for the `Move` bindings. For these bindings, the move is implemented by allocating a *buffer* (whose size is ABI specific) and by moving all the lowered values into positions within this buffer. The buffer is then passed to a piece of assembly code inside the VM which takes values from the buffer and moves them in their expected registers/stack slots (note that each position in the buffer corresponds to a different register). This is the most general invocation mode, the more "customizable" one, but also the slowest - since for every call there is some extra allocation which takes place. > > * specialized interpreted mode; same as before, but instead of interpreting the bindings with a stack-based interpreter, we generate a method handle chain which effectively interprets all the bindings (again, except `Move` ones). > > * intrinsified mode; this is typically used in combination with the specialized interpreted mode described above (although it can also be used with the Java-based binding interpreter). The goal here is to remove the buffer allocation and copy by introducing an additional JVM intrinsic. If a native call recipe is constant (e.g. the set of bindings is constant, which is probably the case if the native method handle is stored in a `static`, `final` field), then the VM can generate specialized assembly code which interprets the `Move` binding without the need to go for an intermediate buffer. This gives us back performances that are on par with JNI. > > For upcalls, the support is not (yet) as advanced, and only the basic interpreted mode is available there. We plan to add support for intrinsified modes there as well, which should considerably boost perfomances (probably well beyond what JNI can offer at the moment, since the upcall support in JNI is not very well optimized). > > Again, for more readings on the internals of the foreign linker support, please refer to [5]. > > #### Test changes > > Many new tests have been added to validate the foreign linker support; we have high level tests (see `StdLibTest`) which aim at testing the linker from the perspective of code that clients could write. But we also have deeper combinatorial tests (see `TestUpcall` and `TestDowncall`) which are meant to stress every corner of the ABI implementation. There are also some great tests (see the `callarranger` folder) which test the various `CallArranger`s for all the possible platforms; these tests adopt more of a white-box approach - that is, instead of treating the linker machinery as a black box and verify that the support works by checking that the native call returned the results we expected, these tests aims at checking that the set of bindings generated by the call arranger is correct. This also mean that we can test the classification logic for Windows, Mac and Linux regardless of the platform we're executing on. > > Some additional microbenchmarks have been added to compare the performances of downcall/upcall with JNI. > > [1] - https://openjdk.java.net/jeps/389 > [2] - https://openjdk.java.net/jeps/393 > [3] - https://git.openjdk.java.net/jdk/pull/548 > [4] - https://github.com/openjdk/panama-foreign/blob/foreign-jextract/doc/panama_ffi.md > [5] - http://cr.openjdk.java.net/~jvernee/docs/Foreign-abi%20downcall%20intrinsics%20technical%20description.html This pull request has now been integrated. Changeset: 0fb31dbf Author: Maurizio Cimadamore URL: https://git.openjdk.java.net/jdk/commit/0fb31dbf Stats: 67469 lines in 212 files changed: 67290 ins; 79 del; 100 mod 8254231: Implementation of Foreign Linker API (Incubator) Reviewed-by: coleenp, ihse, dholmes, vlivanov ------------- PR: https://git.openjdk.java.net/jdk/pull/634 From james.laskey at oracle.com Mon Nov 23 13:27:31 2020 From: james.laskey at oracle.com (Jim Laskey) Date: Mon, 23 Nov 2020 09:27:31 -0400 Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <676865722.1878668.1605655096153.JavaMail.zimbra@u-pem.fr> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <676865722.1878668.1605655096153.JavaMail.zimbra@u-pem.fr> Message-ID: <740D04D2-6FCB-44B7-BC57-6347B27171B5@oracle.com> [Sorry it took so long. Have been on break.] From Guy: Thanks for the forward. Here are my thoughts: Good question from R?mi. If we consider PRNGs to have started at about the time of von Neumann, circa 1946, then I would say that we have been inventing a new category about once every 25 years or so: jumpable, multi-level jumpable, cryptographically secure, splittable. Twenty years ago we would just have one or more levels of jumping/leaping. I think SecureRandom appeared in 2002 (in J2SE 1.4), and the first version of SplittableRandom was in 2014. So I could be wrong, but I really don?t expect to have to add any more interfaces in the next decade or two. I think we will get more benefit from the better type checking than we would get with optional methods. ?Guy > On Nov 17, 2020, at 7:18 PM, Remi Forax wrote: > > An honest question, > why do we need so many interfaces for the different categories of RandomGenerator ? > > My fear is that we are encoding the state of our knowledge of the different kinds of random generators now so it will not be pretty in the future when new categories of random generator are discovered/invented. > If we can take example of the past to predict the future, 20 years ago, what should have been the hierarchy at that time. > Is it not reasonable to think that we will need new kinds of random generator in the future ? > > I wonder if it's not better to have one interface and several optional methods like we have with the collections, it means that we are loosing the possibilities to precisely type a method that only works with a precise type of generator but it will be more future proof. > > R?mi > > ----- Mail original ----- >> De: "Jim Laskey" >> ?: "build-dev" , "core-libs-dev" , >> security-dev at openjdk.java.net >> Envoy?: Mardi 17 Novembre 2020 23:21:18 >> Objet: Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] > >>> This PR is to introduce a new random number API for the JDK. The primary API is >>> found in RandomGenerator and RandomGeneratorFactory. Further description can be >>> found in the JEP https://openjdk.java.net/jeps/356 . >> >> Jim Laskey has updated the pull request with a new target base due to a merge or >> a rebase. The pull request now contains 40 commits: >> >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Update package-info.java >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated RandomGeneratorFactory javadoc. >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated documentation for RandomGeneratorFactory. >> - Merge branch 'master' into 8248862 >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Move RandomGeneratorProperty >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Clear up javadoc >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> >> remove RandomGeneratorProperty from API >> - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 >> >> ------------- >> >> Changes: https://git.openjdk.java.net/jdk/pull/1273/files >> Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1273&range=02 >> Stats: 14891 lines in 31 files changed: 11110 ins; 3704 del; 77 mod >> Patch: https://git.openjdk.java.net/jdk/pull/1273.diff >> Fetch: git fetch https://git.openjdk.java.net/jdk pull/1273/head:pull/1273 >> >> PR: https://git.openjdk.java.net/jdk/pull/1273 From james.laskey at oracle.com Mon Nov 23 13:58:50 2020 From: james.laskey at oracle.com (Jim Laskey) Date: Mon, 23 Nov 2020 09:58:50 -0400 Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: <24865095.1772546.1605960239461.JavaMail.zimbra@u-pem.fr> References: <24865095.1772546.1605960239461.JavaMail.zimbra@u-pem.fr> Message-ID: <20FD1D00-E00C-4320-821E-3CE4F0747A37@oracle.com> R?mi, > On Nov 21, 2020, at 8:03 AM, Remi Forax wrote: > > Ok, i've taking the time to read some literature about random generators because for me the Mersenne Twister was still the king. > > The current API proposed as clearly two levels, you have the user level and the implementation level, at least the implementation level should seen as a SPI Yes, We agree. It was decided that we work on the SPI separately from the original JEP. IMHO the implementation issues are too complex for a single JEP. So, the goal is to release the user level now, and refine the SPI at a later date. Only RandomGenerator (with descendant interfaces) and RandomGeneratorFactory will be public facing in the first release. > > RandomGenerator is the user facing API, for me it should be the sole interface exposed by the API, the others (leap, arbitrary leap and split) should be optional methods. Fair enough, but if your task requires leapable, you might be disappointed when you get an UnsupportedOperationException invoking leap. I personally like the "to the quick" ability of using LeapableGenerator for narrowing down the search. LeapableGenerator leapable = LeapableGenerator.all().findFirst().orElseThrow(); Open for discussion. > > In term of factory methods, we should have user driven methods: > - getDefaultGenerator() that currently returns a L64X128MixRandom and can be changed in the future > - getFastGenerator() that currently returns a Xoroshiro128PlusPlus and can be changed in the future > - getDefault[Splitable|Leapable|etc]Generator that returns a default generator with the methods splits|leaps|etc defined > - of / getByName that returns a specific generator by its name (but mov ed in a SPI class) I'm concerned that the "can be changed in the future" aspect of your default methods will create a false reliance. We sort of have default now with the java.util.Random class. If we were to change the underpinnings of Random all heck would break loose. We already ran into that aspect during testing - tests that relied on sequences from fixed seeds. We try to discourage the use of 'of', but there is a class of user (machine learning for example) that wants to be able to specify exactly. Often, choosing a specific fast prng for testing and then a more sophisticated one for production. The main purpose for RandomGenerator is swapability. > > The example in the documentation should use getDefaultGenerator() and not of() to avoid the problem all the programming languages currently have by having over-specified that the default generator is a Mersenne Twister. I have a problem with this as well. It would make it difficult to deprecate java.util.Random. > > All methods that returns a stream of the available implementations should be moved in the SPI package. Open for discussion. > > R?mi > Cheers, -- Jim > --- > An honest question, > why do we need so many interfaces for the different categories of RandomGenerator ? > > My fear is that we are encoding the state of our knowledge of the different kinds of random generators now so it will not be pretty in the future when new categories of random generator are discovered/invented. > If we can take example of the past to predict the future, 20 years ago, what should have been the hierarchy at that time. > Is it not reasonable to think that we will need new kinds of random generator in the future ? > > I wonder if it's not better to have one interface and several optional methods like we have with the collections, it means that we are loosing the possibilities to precisely type a method that only works with a precise type of generator but it will be more future proof. > > R?mi > > ----- Mail original ----- >> De: "Jim Laskey" >> ?: "core-libs-dev" , "security-dev" >> Envoy?: Mercredi 18 Novembre 2020 14:52:56 >> Objet: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators > >> This PR is to introduce a new random number API for the JDK. The primary API is >> found in RandomGenerator and RandomGeneratorFactory. Further description can be >> found in the JEP https://openjdk.java.net/jeps/356 . >> >> javadoc can be found at >> http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html >> >> old PR: https://github.com/openjdk/jdk/pull/1273 >> >> ------------- >> >> Commit messages: >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> - ... and 15 more: https://git.openjdk.java.net/jdk/compare/f7517386...2b3e4ed7 >> >> Changes: https://git.openjdk.java.net/jdk/pull/1292/files >> Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=00 >> Issue: https://bugs.openjdk.java.net/browse/JDK-8248862 >> Stats: 13319 lines in 25 files changed: 11110 ins; 2132 del; 77 mod >> Patch: https://git.openjdk.java.net/jdk/pull/1292.diff >> Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292 >> >> PR: https://git.openjdk.java.net/jdk/pull/1292 From jlaskey at openjdk.java.net Mon Nov 23 15:01:13 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Mon, 23 Nov 2020 15:01:13 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: On Tue, 17 Nov 2020 21:22:28 GMT, Paul Sandoz wrote: >> Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: >> >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Update package-info.java >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated RandomGeneratorFactory javadoc. >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated documentation for RandomGeneratorFactory. >> - Merge branch 'master' into 8248862 >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Move RandomGeneratorProperty >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Clear up javadoc >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> >> remove RandomGeneratorProperty from API >> - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 > > src/java.base/share/classes/java/util/Random.java line 592: > >> 590: >> 591: @Override >> 592: public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) { > > Unsure if this and the other two methods are intended to be public or not, since they are at the end of the class and override methods of a module private class. In principle there is nothing wrong with such `Spliterator` factories, but wonder if they are really needed given the `Stream` returning methods. The arrangement of classes makes it awkward to hide these methods. Re the properties general comment: I moved properties to RandomSupport based on the notion that the SPI work with come later. Re makeIntsSpliterator: These methods aren't exposed in the java.util.Random API I guess no harm done. The only solution I can think of is to create an intermediate implementor, but that leaves the methods exposed as well. > src/java.base/share/classes/java/util/SplittableRandom.java line 171: > >> 169: * RandomGenerator properties. >> 170: */ >> 171: static Map getProperties() { > > With records exiting preview in 16 this map of properties could i think be represented as a record instance, with better type safety, where `RandomSupport.RandomGeneratorProperty` enum values become typed fields declared on the record class. Something to consider after integration perhaps? Yes. > src/java.base/share/classes/java/util/SplittableRandom.java line 211: > >> 209: * http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html >> 210: */ >> 211: private static long mix64(long z) { > > Usages be replaced with calls to `RandomSupport.mixStafford13`? We were careful to not change the sequences (from fixed seed) generated by existing prngs. This was an edge case. > src/java.base/share/classes/module-info.java line 250: > >> 248: exports jdk.internal.util.xml.impl to >> 249: jdk.jfr; >> 250: exports jdk.internal.util.random; > > Unqualified export, should this be `to jdk.random`? I guess you are right. Until we have a defined SPI we should restrict. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From mullan at openjdk.java.net Mon Nov 23 15:14:07 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 23 Nov 2020 15:14:07 GMT Subject: RFR: 8243559: Remove root certificates with 1024-bit keys Message-ID: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> This change removes five root certificates with 1024-bit RSA public keys from the system-wide `cacerts` keystore. These are older VeriSign and Thawte root CA certificates which are no longer necessary to retain and should have minimal compatibility risk if removed. See the CSR for more details: https://bugs.openjdk.java.net/browse/JDK-8256502 ------------- Commit messages: - 8256502: Remove root certificates with 1024-bit keys Changes: https://git.openjdk.java.net/jdk/pull/1387/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1387&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8243559 Stats: 140 lines in 6 files changed: 0 ins; 138 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/1387.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1387/head:pull/1387 PR: https://git.openjdk.java.net/jdk/pull/1387 From jlaskey at openjdk.java.net Mon Nov 23 15:20:13 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Mon, 23 Nov 2020 15:20:13 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: On Tue, 17 Nov 2020 23:46:12 GMT, Paul Sandoz wrote: >> Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: >> >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Update package-info.java >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated RandomGeneratorFactory javadoc. >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated documentation for RandomGeneratorFactory. >> - Merge branch 'master' into 8248862 >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Move RandomGeneratorProperty >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Clear up javadoc >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> >> remove RandomGeneratorProperty from API >> - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 > > src/jdk.random/share/classes/module-info.java line 53: > >> 51: uses RandomSupport; >> 52: >> 53: exports jdk.random to > > Why is this needed? Removing > src/java.base/share/classes/java/util/random/package-info.java line 50: > >> 48: * given its name. >> 49: * >> 50: *

The principal supporting class is {@link RandomGenertatorFactor}. This > > s/RandomGenertatorFactor/RandomGenertatorFactory fixing > src/java.base/share/classes/java/util/random/package-info.java line 140: > >> 138: * >> 139: *

For applications with no special requirements, >> 140: * "L64X128MixRandom" has a good balance among speed, space, > > The documentation assumes that the `jdk.random` module is present in the JDK image. Perhaps we need to spit the specifics to `jdk.random`? But jdk.random isn't really a public API. > src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 1211: > >> 1209: Udiff = -Udiff; >> 1210: U2 = U1; >> 1211: U1 -= Udiff; > > Updated `U1` never used (recommend running the code through a checker e.g. use IntelliJ) I noticed that before. I think it's a symmetry thing - will check with Guy. > src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 1157: > >> 1155: /* >> 1156: * The tables themselves, as well as a number of associated parameters, are >> 1157: * defined in class java.util.DoubleZigguratTables, which is automatically > > `DoubleZigguratTables` is an inner class of `RandomSupport` Late change fixing. > src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 2895: > >> 2893: * distribution: 0.0330 >> 2894: */ >> 2895: static class DoubleZigguratTables { > > make `final` fixing > src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 167: > >> 165: * Return the properties map for the specified provider. >> 166: * >> 167: * @param provider provider to locate. > > Method has no such parameter Fixing ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Mon Nov 23 15:20:01 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Mon, 23 Nov 2020 15:20:01 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: On Mon, 23 Nov 2020 14:57:59 GMT, Jim Laskey wrote: >> src/java.base/share/classes/module-info.java line 250: >> >>> 248: exports jdk.internal.util.xml.impl to >>> 249: jdk.jfr; >>> 250: exports jdk.internal.util.random; >> >> Unqualified export, should this be `to jdk.random`? > > I guess you are right. Until we have a defined SPI we should restrict. On the other hand: public class Random extends AbstractSpliteratorGenerator ^ error: warnings found and -Werror specified public final class SplittableRandom extends AbstractSplittableGenerator { ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Mon Nov 23 15:24:09 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Mon, 23 Nov 2020 15:24:09 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: On Wed, 18 Nov 2020 00:29:36 GMT, Paul Sandoz wrote: >> Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: >> >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Update package-info.java >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated RandomGeneratorFactory javadoc. >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated documentation for RandomGeneratorFactory. >> - Merge branch 'master' into 8248862 >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Move RandomGeneratorProperty >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Clear up javadoc >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> >> remove RandomGeneratorProperty from API >> - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 > > src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 173: > >> 171: @SuppressWarnings("unchecked") >> 172: private Map getProperties() { >> 173: if (properties == null) { > > `properties` needs to be marked volatile, and it needs to be assigned at line 182 or line 184. One of them foggy days. ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Mon Nov 23 15:36:58 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Mon, 23 Nov 2020 15:36:58 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators In-Reply-To: References: Message-ID: On Fri, 20 Nov 2020 23:30:03 GMT, Roger Baumgartner wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . >> >> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html >> >> old PR: https://github.com/openjdk/jdk/pull/1273 > > src/java.base/share/classes/java/util/random/package-info.java line 149: > >> 147: * >> 148: *

For an application running in a 32-bit hardware environment and using >> 149: * only one thread or a small number of threads, may be a good choice. > > I think the name of the suitable algorithm is missing here. Yes - "L32X64MixRandom". Thank you. ------------- PR: https://git.openjdk.java.net/jdk/pull/1292 From weijun at openjdk.java.net Mon Nov 23 15:49:59 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 23 Nov 2020 15:49:59 GMT Subject: RFR: 8243559: Remove root certificates with 1024-bit keys In-Reply-To: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> References: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> Message-ID: On Mon, 23 Nov 2020 15:08:13 GMT, Sean Mullan wrote: > This change removes five root certificates with 1024-bit RSA public keys from the system-wide `cacerts` keystore. These are older VeriSign and Thawte root CA certificates which are no longer necessary to retain and should have minimal compatibility risk if removed. > > See the CSR for more details: https://bugs.openjdk.java.net/browse/JDK-8256502 Marked as reviewed by weijun (Reviewer). Looks fine. One nit: I see that the `VerifyCACerts.java` test has a whole bunch of `@bug` ids. Maybe we should add this new one as well? ------------- PR: https://git.openjdk.java.net/jdk/pull/1387 From jlaskey at openjdk.java.net Mon Nov 23 15:53:00 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Mon, 23 Nov 2020 15:53:00 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v2] In-Reply-To: References: Message-ID: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html > > old PR: https://github.com/openjdk/jdk/pull/1273 Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: Review changes @PaulSandoz and @rogermb ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1292/files - new: https://git.openjdk.java.net/jdk/pull/1292/files/2b3e4ed7..9d6d1a94 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=00-01 Stats: 18 lines in 4 files changed: 2 ins; 5 del; 11 mod Patch: https://git.openjdk.java.net/jdk/pull/1292.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292 PR: https://git.openjdk.java.net/jdk/pull/1292 From mullan at openjdk.java.net Mon Nov 23 16:24:00 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 23 Nov 2020 16:24:00 GMT Subject: RFR: 8243559: Remove root certificates with 1024-bit keys In-Reply-To: References: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> Message-ID: On Mon, 23 Nov 2020 15:47:25 GMT, Weijun Wang wrote: >> This change removes five root certificates with 1024-bit RSA public keys from the system-wide `cacerts` keystore. These are older VeriSign and Thawte root CA certificates which are no longer necessary to retain and should have minimal compatibility risk if removed. >> >> See the CSR for more details: https://bugs.openjdk.java.net/browse/JDK-8256502 > > Marked as reviewed by weijun (Reviewer). > Looks fine. > > One nit: I see that the `VerifyCACerts.java` test has a whole bunch of `@bug` ids. Maybe we should add this new one as well? Good catch. I will add it. ------------- PR: https://git.openjdk.java.net/jdk/pull/1387 From mullan at openjdk.java.net Tue Nov 24 14:07:08 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Tue, 24 Nov 2020 14:07:08 GMT Subject: RFR: 8243559: Remove root certificates with 1024-bit keys [v2] In-Reply-To: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> References: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> Message-ID: <4zPjmPZ7Veq6AOuQY8SbC-YFjFl4w92g9S6cgeFiPU0=.d4424955-fa3f-4b00-bedd-fdb0967b982e@github.com> > This change removes five root certificates with 1024-bit RSA public keys from the system-wide `cacerts` keystore. These are older VeriSign and Thawte root CA certificates which are no longer necessary to retain and should have minimal compatibility risk if removed. > > See the CSR for more details: https://bugs.openjdk.java.net/browse/JDK-8256502 Sean Mullan has updated the pull request incrementally with one additional commit since the last revision: Add bugid to @bug. ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1387/files - new: https://git.openjdk.java.net/jdk/pull/1387/files/dd7a3508..dc1c57e2 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1387&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1387&range=00-01 Stats: 1 line in 1 file changed: 1 ins; 0 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/1387.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1387/head:pull/1387 PR: https://git.openjdk.java.net/jdk/pull/1387 From sean.mullan at oracle.com Tue Nov 24 16:23:56 2020 From: sean.mullan at oracle.com (Sean Mullan) Date: Tue, 24 Nov 2020 11:23:56 -0500 Subject: RFR 8153005: Upgrade the default PKCS12 encryption/MAC algorithms In-Reply-To: References: <907C5852-0A7B-493F-8A8D-A8EB4B57D67B@oracle.com> Message-ID: <2367016f-ff69-5af6-bf21-b1a3cf4d4c82@oracle.com> On 11/17/20 4:38 PM, Weijun Wang wrote: > > >> On Apr 10, 2020, at 5:03 AM, Weijun Wang wrote: >> >> Please take a review at >> >> CSR : 8228481: Upgrade the default PKCS12 encryption/MAC algorithms >> Release note : https://bugs.openjdk.java.net/browse/JDK-8242069 > > > I forget if the release note has been reviewed before. If not, please take a look. I made a few small wording changes and added "keystore.pkcs12" for the security properties to look for more information. --Sean > > Thanks, > Max > >> webrev : http://cr.openjdk.java.net/~weijun/8153005/webrev.00/ >> >> The default pkcs12 algorithms are bumped into PBE and HMAC based on SHA-256 and AES-256. >> >> Thanks, >> Max >> > From WEIJUN.WANG at ORACLE.COM Tue Nov 24 16:28:34 2020 From: WEIJUN.WANG at ORACLE.COM (Weijun Wang) Date: Tue, 24 Nov 2020 11:28:34 -0500 Subject: RFR 8153005: Upgrade the default PKCS12 encryption/MAC algorithms In-Reply-To: <2367016f-ff69-5af6-bf21-b1a3cf4d4c82@oracle.com> References: <907C5852-0A7B-493F-8A8D-A8EB4B57D67B@oracle.com> <2367016f-ff69-5af6-bf21-b1a3cf4d4c82@oracle.com> Message-ID: <63E14557-EBFC-437F-BD26-1567A3AFE5F9@ORACLE.COM> Is ?keystore.pkcs12.*? better? Or, maybe more clear? See the security properties starting with `keystore.pkcs12` in the `java.security` file for detailed information. Thanks, Max > On Nov 24, 2020, at 11:23 AM, Sean Mullan wrote: > > On 11/17/20 4:38 PM, Weijun Wang wrote: >>> On Apr 10, 2020, at 5:03 AM, Weijun Wang wrote: >>> >>> Please take a review at >>> >>> CSR : 8228481: Upgrade the default PKCS12 encryption/MAC algorithms >>> Release note : https://bugs.openjdk.java.net/browse/JDK-8242069 >> I forget if the release note has been reviewed before. If not, please take a look. > > I made a few small wording changes and added "keystore.pkcs12" for the security properties to look for more information. > > --Sean > >> Thanks, >> Max >>> webrev : http://cr.openjdk.java.net/~weijun/8153005/webrev.00/ >>> >>> The default pkcs12 algorithms are bumped into PBE and HMAC based on SHA-256 and AES-256. >>> >>> Thanks, >>> Max >>> From sean.mullan at oracle.com Tue Nov 24 16:34:26 2020 From: sean.mullan at oracle.com (Sean Mullan) Date: Tue, 24 Nov 2020 11:34:26 -0500 Subject: RFR 8153005: Upgrade the default PKCS12 encryption/MAC algorithms In-Reply-To: <63E14557-EBFC-437F-BD26-1567A3AFE5F9@ORACLE.COM> References: <907C5852-0A7B-493F-8A8D-A8EB4B57D67B@oracle.com> <2367016f-ff69-5af6-bf21-b1a3cf4d4c82@oracle.com> <63E14557-EBFC-437F-BD26-1567A3AFE5F9@ORACLE.COM> Message-ID: On 11/24/20 11:28 AM, Weijun Wang wrote: > Is ?keystore.pkcs12.*? better? Or, maybe more clear? > > See the security properties starting with `keystore.pkcs12` in the `java.security` file for detailed information. "starting with" should be sufficient, I think. No need for the asterisk. --Sean > > Thanks, > Max > >> On Nov 24, 2020, at 11:23 AM, Sean Mullan wrote: >> >> On 11/17/20 4:38 PM, Weijun Wang wrote: >>>> On Apr 10, 2020, at 5:03 AM, Weijun Wang wrote: >>>> >>>> Please take a review at >>>> >>>> CSR : 8228481: Upgrade the default PKCS12 encryption/MAC algorithms >>>> Release note : https://bugs.openjdk.java.net/browse/JDK-8242069 >>> I forget if the release note has been reviewed before. If not, please take a look. >> >> I made a few small wording changes and added "keystore.pkcs12" for the security properties to look for more information. >> >> --Sean >> >>> Thanks, >>> Max >>>> webrev : http://cr.openjdk.java.net/~weijun/8153005/webrev.00/ >>>> >>>> The default pkcs12 algorithms are bumped into PBE and HMAC based on SHA-256 and AES-256. >>>> >>>> Thanks, >>>> Max >>>> > From mullan at openjdk.java.net Tue Nov 24 18:16:59 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Tue, 24 Nov 2020 18:16:59 GMT Subject: Integrated: 8243559: Remove root certificates with 1024-bit keys In-Reply-To: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> References: <-8utnm55fb3iuZpYtA-RbkbARBwlSRN2HORdsRJ2oJc=.3f5b5d9c-665b-4232-8dfd-a7df00f516c4@github.com> Message-ID: <6PMY64JC-6ykNPo57sheC1paYlBIxeaaJ_bALO3TiiQ=.95e5867c-1cdb-4f0d-81c1-52068d935746@github.com> On Mon, 23 Nov 2020 15:08:13 GMT, Sean Mullan wrote: > This change removes five root certificates with 1024-bit RSA public keys from the system-wide `cacerts` keystore. These are older VeriSign and Thawte root CA certificates which are no longer necessary to retain and should have minimal compatibility risk if removed. > > See the CSR for more details: https://bugs.openjdk.java.net/browse/JDK-8256502 This pull request has now been integrated. Changeset: dbfeb90d Author: Sean Mullan URL: https://git.openjdk.java.net/jdk/commit/dbfeb90d Stats: 141 lines in 6 files changed: 1 ins; 138 del; 2 mod 8243559: Remove root certificates with 1024-bit keys Reviewed-by: weijun ------------- PR: https://git.openjdk.java.net/jdk/pull/1387 From jlaskey at openjdk.java.net Tue Nov 24 22:31:08 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Tue, 24 Nov 2020 22:31:08 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> References: <17ZVd3Hqa05Hm2lbHEiXi38RXG__C09KL0QLBqxsb0g=.ef1bca7a-8ec3-4cae-b457-680e739887ea@github.com> <6h9eeR6HFk03eD3DCtXjJo9Wg81zWH1090paXb-Yp1k=.da9e5ecd-377a-488f-a2f6-b43876af6f60@github.com> <2I2HK8tDFSLtPqs0JFLKLgh3QmMTkM1HKuvKQNmsfIg=.a383a449-18e3-413a-a6ba-91dc80fde86a@github.com> Message-ID: On Wed, 18 Nov 2020 00:30:53 GMT, Paul Sandoz wrote: >> Jim Laskey has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains 40 commits: >> >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Update package-info.java >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated RandomGeneratorFactory javadoc. >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Updated documentation for RandomGeneratorFactory. >> - Merge branch 'master' into 8248862 >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Move RandomGeneratorProperty >> - Merge branch 'master' into 8248862 >> - 8248862: Implement Enhanced Pseudo-Random Number Generators >> >> Clear up javadoc >> - 8248862; Implement Enhanced Pseudo-Random Number Generators >> >> remove RandomGeneratorProperty from API >> - ... and 30 more: https://git.openjdk.java.net/jdk/compare/f7517386...6fe94c68 > > src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 148: > >> 146: */ >> 147: private static Map> getFactoryMap() { >> 148: if (factoryMap == null) { > > `factoryMap` needs to be marked volatile when using the double checked locking idiom. fixing > src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 320: > >> 318: } >> 319: } >> 320: } > > Add an `assert` statement that `ctor`, `ctorLong` and `ctorBytes` are all non-null? Only `ctor` is required but yes. > src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 331: > >> 329: */ >> 330: private void ensureConstructors() { >> 331: if (ctor == null) { > > This check occurs outside of the synchronized block, field may need to be marked volatile. Unsure about the other dependent fields. Might need to store values from loop in `getConstructors` in locals and then assign in appropriate order, assigning the volatile field last. okay ------------- PR: https://git.openjdk.java.net/jdk/pull/1273 From jlaskey at openjdk.java.net Wed Nov 25 13:09:03 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Wed, 25 Nov 2020 13:09:03 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: References: Message-ID: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html > > old PR: https://github.com/openjdk/jdk/pull/1273 Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: 8248862: Implement Enhanced Pseudo-Random Number Generators Changes to RandomGeneratorFactory requested by @PaulSandoz ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1292/files - new: https://git.openjdk.java.net/jdk/pull/1292/files/9d6d1a94..802fa530 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=01-02 Stats: 54 lines in 1 file changed: 23 ins; 7 del; 24 mod Patch: https://git.openjdk.java.net/jdk/pull/1292.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292 PR: https://git.openjdk.java.net/jdk/pull/1292 From github.com+828220+forax at openjdk.java.net Wed Nov 25 13:30:05 2020 From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax) Date: Wed, 25 Nov 2020 13:30:05 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: References: Message-ID: On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . >> >> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html >> >> old PR: https://github.com/openjdk/jdk/pull/1273 > > Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: > > 8248862: Implement Enhanced Pseudo-Random Number Generators > > Changes to RandomGeneratorFactory requested by @PaulSandoz src/java.base/share/classes/java/security/SecureRandom.java line 223: > 221: Map.entry(RandomGeneratorProperty.IS_HARDWARE, false) > 222: ); > 223: } Using Map.of() instead of Map.ofEntries() should simplify the code src/java.base/share/classes/java/util/Random.java line 129: > 127: Map.entry(RandomGeneratorProperty.IS_HARDWARE, false) > 128: ); > 129: } Using Map.of() should simplify the code src/java.base/share/classes/java/util/SplittableRandom.java line 181: > 179: Map.entry(RandomGeneratorProperty.IS_HARDWARE, false) > 180: ); > 181: } Using Map.of() should simplify the code src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 169: > 167: Map.entry(RandomGeneratorProperty.IS_STOCHASTIC, false), > 168: Map.entry(RandomGeneratorProperty.IS_HARDWARE, false) > 169: ); Using Map.of() should simplify the code src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 433: > 431: private static final class ThreadLocalRandomProxy extends Random { > 432: @java.io.Serial > 433: static final long serialVersionUID = 0L; should be private src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 444: > 442: } > 443: > 444: private static final AbstractSpliteratorGenerator proxy = new ThreadLocalRandomProxy(); should be declared inside ThreadLocalRandomProxy, so the value is only initialized when proxy() is called src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 453: > 451: * @return a {@code RandomGenerator} object that uses {@code ThreadLocalRandom} > 452: */ > 453: public static RandomGenerator proxy() { proxy is a generic name, is there a better name here ? src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 459: > 457: // Methods required by class AbstractSpliteratorGenerator > 458: public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) { > 459: return new RandomIntsSpliterator(proxy, index, fence, origin, bound); should use proxy() ------------- PR: https://git.openjdk.java.net/jdk/pull/1292 From github.com+828220+forax at openjdk.java.net Wed Nov 25 13:35:02 2020 From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax) Date: Wed, 25 Nov 2020 13:35:02 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: References: Message-ID: On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . >> >> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html >> >> old PR: https://github.com/openjdk/jdk/pull/1273 > > Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: > > 8248862: Implement Enhanced Pseudo-Random Number Generators > > Changes to RandomGeneratorFactory requested by @PaulSandoz src/java.base/share/classes/java/util/random/RandomGenerator.java line 745: > 743: * if the period is unknown. > 744: */ > 745: BigInteger UNKNOWN_PERIOD = BigInteger.ZERO; move those 3 values into RandomGeneratorFactory ? ------------- PR: https://git.openjdk.java.net/jdk/pull/1292 From github.com+828220+forax at openjdk.java.net Wed Nov 25 13:41:04 2020 From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax) Date: Wed, 25 Nov 2020 13:41:04 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3] In-Reply-To: References: Message-ID: On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey wrote: >> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . >> >> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html >> >> old PR: https://github.com/openjdk/jdk/pull/1273 > > Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: > > 8248862: Implement Enhanced Pseudo-Random Number Generators > > Changes to RandomGeneratorFactory requested by @PaulSandoz src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 88: > 86: *

{@code
> 87:  *     RandomGeneratorFactory best = RandomGenerator.all()
> 88:  *         .sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))

use Comparator.comparingInt(RandomGenerator::stateBits) instead of the lambda

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 116:

> 114:      * Map of properties for provider.
> 115:      */
> 116:     private volatile Map properties = null;

`= null` is useless here

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 106:

> 104:      * Map of provider classes.
> 105:      */
> 106:     private static volatile Map> factoryMap;

should be FACTORY_MAP given that it's a static field

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 13:54:05 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 13:54:05 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
Message-ID: <_I5a2hVdcTFOW9m0hiZevWblT1ws6XTyTEiIVqobG5E=.2aa95467-1461-4445-9af8-c8ffe856e47e@github.com>

On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey  wrote:

>> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
>> 
>> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
>> 
>> old PR:  https://github.com/openjdk/jdk/pull/1273
>
> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8248862: Implement Enhanced Pseudo-Random Number Generators
>   
>   Changes to RandomGeneratorFactory requested by @PaulSandoz

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 151:

> 149:         if (fm == null) {
> 150:             synchronized (RandomGeneratorFactory.class) {
> 151:                 if (RandomGeneratorFactory.factoryMap == null) {

if `RandomGeneratorFactory.factoryMap` is not null, it returns null because the value is not stored in fm.

Please use the class holder idiom (cf Effective Java)  instead of using the double-check locking pattern.

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 157:

> 155:                             .stream()
> 156:                             .filter(p -> !p.type().isInterface())
> 157:                             .collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(),

toUpperCase() depends on the Locale !

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 175:

> 173:         if (props == null) {
> 174:             synchronized (provider) {
> 175:                 if (properties == null) {

same issue with the double check locking

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 177:

> 175:                 if (properties == null) {
> 176:                     try {
> 177:                         Method getProperties = provider.type().getDeclaredMethod("getProperties");

Is it not a better way than using reflection here ?

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 180:

> 178:                         PrivilegedExceptionAction> getAction = () -> {
> 179:                             getProperties.setAccessible(true);
> 180:                             return (Map)getProperties.invoke(null);

Given that we have no control over the fact that the method properties() doesn't return a Map of something else, this unsafe cast seems dangerous (from the type system POV).

Having a type representing a reified version of the Map may be a better idea

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 13:54:07 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 13:54:07 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 25 Nov 2020 13:24:37 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 433:
> 
>> 431:     private static final class ThreadLocalRandomProxy extends Random {
>> 432:         @java.io.Serial
>> 433:         static final long serialVersionUID = 0L;
> 
> should be private

(instance?) agree

> src/java.base/share/classes/java/security/SecureRandom.java line 223:
> 
>> 221:                 Map.entry(RandomGeneratorProperty.IS_HARDWARE, false)
>> 222:         );
>> 223:     }
> 
> Using Map.of() instead of Map.ofEntries() should simplify the code

I had assumed  Map.ofEntries() was more efficient but it seems it in turn uses MapN as well. Will change these cases.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 14:04:08 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 14:04:08 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
Message-ID: <6GrCVkOLBO0i67Fuw_NPXWzZ49D0fsfLpHNI_NZRHDg=.97fda7db-4d50-4fa2-8062-c2f10396d589@github.com>

On Wed, 25 Nov 2020 13:31:52 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGenerator.java line 745:
> 
>> 743:      * if the period is unknown.
>> 744:      */
>> 745:     BigInteger UNKNOWN_PERIOD = BigInteger.ZERO;
> 
> move those 3 values into RandomGeneratorFactory ?

Will ponder on this one. I tend to agree with you since they are most likely to be used for filtering factories RandomGeneratorFactory querying was a later development. period() originally was a RandomGenerator query, but got moved when more queries were added. This will require a CSR and will come later.

> src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 444:
> 
>> 442:     }
>> 443: 
>> 444:     private static final AbstractSpliteratorGenerator proxy = new ThreadLocalRandomProxy();
> 
> should be declared inside ThreadLocalRandomProxy, so the value is only initialized when proxy() is called

agree

> src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 453:
> 
>> 451:      * @return a {@code RandomGenerator} object that uses {@code ThreadLocalRandom}
>> 452:      */
>> 453:     public static RandomGenerator proxy() {
> 
> proxy is a generic name, is there a better name here ?

will investigate

> src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 459:
> 
>> 457:     // Methods required by class AbstractSpliteratorGenerator
>> 458:     public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
>> 459:         return new RandomIntsSpliterator(proxy, index, fence, origin, bound);
> 
> should use proxy()

will investigate

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 14:04:02 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 14:04:02 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
Message-ID: <3qYZQ8Bnkp26ReuTglCIHf6SZ7RFEIQty9sBsNDJhxk=.e2036b7c-abf7-4c55-8fc6-23dee9c4dc72@github.com>

On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey  wrote:

>> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
>> 
>> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
>> 
>> old PR:  https://github.com/openjdk/jdk/pull/1273
>
> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8248862: Implement Enhanced Pseudo-Random Number Generators
>   
>   Changes to RandomGeneratorFactory requested by @PaulSandoz

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 235:

> 233:             throws IllegalArgumentException {
> 234:         Map> fm = getFactoryMap();
> 235:         Provider provider = fm.get(name.toUpperCase());

again use of toUpperCase() instead of toUpperCase(Locale)

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 250:

> 248:      * @return Stream of matching Providers.
> 249:      */
> 250:     static  Stream> all(Class category) {

this signature is weird, T is not used in the parameter, so in case return any type of Stream> from a type POV, should it be
`  Stream> all(Class category)` instead ?

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 269:

> 267:      * @throws IllegalArgumentException when either the name or category is null
> 268:      */
> 269:     static  T of(String name, Class category)

Same issue as above, T is not used as a constraint

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 288:

> 286:      * @throws IllegalArgumentException when either the name or category is null
> 287:      */
> 288:     static  RandomGeneratorFactory factoryOf(String name, Class category)

Same as above

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 300:

> 298:      */
> 299:     @SuppressWarnings("unchecked")
> 300:     private void getConstructors(Class randomGeneratorClass) {

method name get but do side effects

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 14:16:05 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 14:16:05 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
Message-ID: 

On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey  wrote:

>> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
>> 
>> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
>> 
>> old PR:  https://github.com/openjdk/jdk/pull/1273
>
> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8248862: Implement Enhanced Pseudo-Random Number Generators
>   
>   Changes to RandomGeneratorFactory requested by @PaulSandoz

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 335:

> 333:                         ctorBytes = tmpCtorBytes;
> 334:                         ctorLong = tmpCtorLong;
> 335:                         ctor = tmpCtor;

This one is a volatile write, so the idea is that ctorBytes and ctorLong does not need to be volatile too, which i think is not true if there is a code somewhere that uses ctorBytes or ctorLong without reading ctor.
This code is too smart for me, i'm pretty sure it is wrong too on non TSO cpu.

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 480:

> 478:         } catch (Exception ex) {
> 479:             // Should never happen.
> 480:             throw new IllegalStateException("Random algorithm " + name() + " is missing a default constructor");

chain the exception ...

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 497:

> 495:             ensureConstructors();
> 496:             return ctorLong.newInstance(seed);
> 497:         } catch (Exception ex) {

this one is very dubious because the result in an exception is thrown is a random generator with the wrong seed

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 517:

> 515:             ensureConstructors();
> 516:             return ctorBytes.newInstance((Object)seed);
> 517:         } catch (Exception ex) {

same as above

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 14:19:02 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 14:19:02 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
Message-ID: 

On Wed, 25 Nov 2020 13:09:03 GMT, Jim Laskey  wrote:

>> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
>> 
>> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
>> 
>> old PR:  https://github.com/openjdk/jdk/pull/1273
>
> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
> 
>   8248862: Implement Enhanced Pseudo-Random Number Generators
>   
>   Changes to RandomGeneratorFactory requested by @PaulSandoz

src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 46:

> 44: import java.util.stream.Stream;
> 45: import jdk.internal.util.random.RandomSupport.RandomGeneratorProperty;
> 46: 

Instead of calling a method properties to create a Map, it's usually far easier to use an annotation,
annotation values supports less runtime type so BigInteger is not supported but using a String instead should be OK.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 15:46:00 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 15:46:00 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: <6GrCVkOLBO0i67Fuw_NPXWzZ49D0fsfLpHNI_NZRHDg=.97fda7db-4d50-4fa2-8062-c2f10396d589@github.com>
References: 
 
 
 <6GrCVkOLBO0i67Fuw_NPXWzZ49D0fsfLpHNI_NZRHDg=.97fda7db-4d50-4fa2-8062-c2f10396d589@github.com>
Message-ID: 

On Wed, 25 Nov 2020 13:55:52 GMT, Jim Laskey  wrote:

>> src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 453:
>> 
>>> 451:      * @return a {@code RandomGenerator} object that uses {@code ThreadLocalRandom}
>>> 452:      */
>>> 453:     public static RandomGenerator proxy() {
>> 
>> proxy is a generic name, is there a better name here ?
>
> will investigate

agree

>> src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java line 459:
>> 
>>> 457:     // Methods required by class AbstractSpliteratorGenerator
>>> 458:     public Spliterator.OfInt makeIntsSpliterator(long index, long fence, int origin, int bound) {
>>> 459:         return new RandomIntsSpliterator(proxy, index, fence, origin, bound);
>> 
>> should use proxy()
>
> will investigate

Needed to use ThreadLocalRandomProxy.proxy otherwise a cast would be required.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 16:03:04 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 16:03:04 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 25 Nov 2020 13:37:02 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 88:
> 
>> 86:  * 
{@code
>> 87:  *     RandomGeneratorFactory best = RandomGenerator.all()
>> 88:  *         .sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))
> 
> use Comparator.comparingInt(RandomGenerator::stateBits) instead of the lambda

Not sure that `.sorted(Comparator.comparingInt(RandomGeneratorFactory::stateBits).reversed())` is simpler than  `.sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))`.

> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 116:
> 
>> 114:      * Map of properties for provider.
>> 115:      */
>> 116:     private volatile Map properties = null;
> 
> `= null` is useless here

agree

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 16:26:03 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 16:26:03 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
 <6GrCVkOLBO0i67Fuw_NPXWzZ49D0fsfLpHNI_NZRHDg=.97fda7db-4d50-4fa2-8062-c2f10396d589@github.com>
 
Message-ID: 

On Wed, 25 Nov 2020 15:43:39 GMT, Jim Laskey  wrote:

>> will investigate
>
> Needed to use ThreadLocalRandomProxy.proxy otherwise a cast would be required.

yes, right !

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 16:26:02 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 16:26:02 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 25 Nov 2020 13:38:59 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 106:
> 
>> 104:      * Map of provider classes.
>> 105:      */
>> 106:     private static volatile Map> factoryMap;
> 
> should be FACTORY_MAP given that it's a static field

will fall out of using  class holder idiom

> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 151:
> 
>> 149:         if (fm == null) {
>> 150:             synchronized (RandomGeneratorFactory.class) {
>> 151:                 if (RandomGeneratorFactory.factoryMap == null) {
> 
> if `RandomGeneratorFactory.factoryMap` is not null, it returns null because the value is not stored in fm.
> 
> Please use the class holder idiom (cf Effective Java)  instead of using the double-check locking pattern.

? set in 148 and 152, but  class holder idiom +1

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 16:28:58 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 16:28:58 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
 
Message-ID: <4scjt1TdYV9Z6bN6YheIELaKERWLpvqE_fyR9bMNPEE=.c986e3d1-6a62-42c2-b087-4e7d47850ffb@github.com>

On Wed, 25 Nov 2020 15:59:01 GMT, Jim Laskey  wrote:

>> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 88:
>> 
>>> 86:  * 
{@code
>>> 87:  *     RandomGeneratorFactory best = RandomGenerator.all()
>>> 88:  *         .sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))
>> 
>> use Comparator.comparingInt(RandomGenerator::stateBits) instead of the lambda
>
> Not sure that `.sorted(Comparator.comparingInt(RandomGeneratorFactory::stateBits).reversed())` is simpler than  `.sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))`.

At least, it's more clear that it's reversed, i've initially miss the fact that f and g are swapped.
And :: is able to do inference so, i believe it can be written
  `.sorted(Comparator.comparingInt(RandomGeneratorFactory::stateBits).reversed())`

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 16:32:03 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 16:32:03 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
 
Message-ID: <_2MGrO5lSf9qR4OHLxci2tlDMjJlvAKu6m-n7XYPJO0=.84e85b82-8670-4c78-8842-04dace3a3d55@github.com>

On Wed, 25 Nov 2020 16:22:34 GMT, Jim Laskey  wrote:

>> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 151:
>> 
>>> 149:         if (fm == null) {
>>> 150:             synchronized (RandomGeneratorFactory.class) {
>>> 151:                 if (RandomGeneratorFactory.factoryMap == null) {
>> 
>> if `RandomGeneratorFactory.factoryMap` is not null, it returns null because the value is not stored in fm.
>> 
>> Please use the class holder idiom (cf Effective Java)  instead of using the double-check locking pattern.
>
> ? set in 148 and 152, but  class holder idiom +1

If the second `RandomGeneratorFactory.factoryMap` return a non null value ...

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 17:15:05 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 17:15:05 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: <_I5a2hVdcTFOW9m0hiZevWblT1ws6XTyTEiIVqobG5E=.2aa95467-1461-4445-9af8-c8ffe856e47e@github.com>
References: 
 
 <_I5a2hVdcTFOW9m0hiZevWblT1ws6XTyTEiIVqobG5E=.2aa95467-1461-4445-9af8-c8ffe856e47e@github.com>
Message-ID: 

On Wed, 25 Nov 2020 13:45:46 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 157:
> 
>> 155:                             .stream()
>> 156:                             .filter(p -> !p.type().isInterface())
>> 157:                             .collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(),
> 
> toUpperCase() depends on the Locale !

It was a lame thing to do anyway - removed

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 19:21:02 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 19:21:02 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: <3qYZQ8Bnkp26ReuTglCIHf6SZ7RFEIQty9sBsNDJhxk=.e2036b7c-abf7-4c55-8fc6-23dee9c4dc72@github.com>
References: 
 
 <3qYZQ8Bnkp26ReuTglCIHf6SZ7RFEIQty9sBsNDJhxk=.e2036b7c-abf7-4c55-8fc6-23dee9c4dc72@github.com>
Message-ID: 

On Wed, 25 Nov 2020 13:54:47 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 235:
> 
>> 233:             throws IllegalArgumentException {
>> 234:         Map> fm = getFactoryMap();
>> 235:         Provider provider = fm.get(name.toUpperCase());
> 
> again use of toUpperCase() instead of toUpperCase(Locale)

removed

> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 250:
> 
>> 248:      * @return Stream of matching Providers.
>> 249:      */
>> 250:     static  Stream> all(Class category) {
> 
> this signature is weird, T is not used in the parameter, so in case return any type of Stream> from a type POV, should it be
> `  Stream> all(Class category)` instead ?

agree

> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 269:
> 
>> 267:      * @throws IllegalArgumentException when either the name or category is null
>> 268:      */
>> 269:     static  T of(String name, Class category)
> 
> Same issue as above, T is not used as a constraint

agree

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 19:48:56 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 19:48:56 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v4]
In-Reply-To: 
References: 
Message-ID: 

> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
> 
> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
> 
> old PR:  https://github.com/openjdk/jdk/pull/1273

Jim Laskey has updated the pull request incrementally with two additional commits since the last revision:

 - 8248862: Implement Enhanced Pseudo-Random Number Generators
   
   Fix extends
 - 8248862: Implement Enhanced Pseudo-Random Number Generators
   
   Use Map.of instead of Map.ofEntries

-------------

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/1292/files
  - new: https://git.openjdk.java.net/jdk/pull/1292/files/802fa530..ee8f87c3

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=03
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=02-03

  Stats: 169 lines in 15 files changed: 23 ins; 17 del; 129 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1292.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Wed Nov 25 19:51:00 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Wed, 25 Nov 2020 19:51:00 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: <4scjt1TdYV9Z6bN6YheIELaKERWLpvqE_fyR9bMNPEE=.c986e3d1-6a62-42c2-b087-4e7d47850ffb@github.com>
References: 
 
 
 
 <4scjt1TdYV9Z6bN6YheIELaKERWLpvqE_fyR9bMNPEE=.c986e3d1-6a62-42c2-b087-4e7d47850ffb@github.com>
Message-ID: 

On Wed, 25 Nov 2020 16:26:12 GMT, R?mi Forax  wrote:

>> Not sure that `.sorted(Comparator.comparingInt(RandomGeneratorFactory::stateBits).reversed())` is simpler than  `.sorted((f, g) -> Integer.compare(g.stateBits(), f.stateBits()))`.
>
> At least, it's more clear that it's reversed, i've initially miss the fact that f and g are swapped.
> And :: is able to do inference so, i believe it can be written
>   `.sorted(Comparator.comparingInt(RandomGeneratorFactory::stateBits).reversed())`

Unfortunately it couldn't be inferred

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From mullan at openjdk.java.net  Wed Nov 25 20:29:02 2020
From: mullan at openjdk.java.net (Sean Mullan)
Date: Wed, 25 Nov 2020 20:29:02 GMT
Subject: RFR: 8257083: Security infra test failures caused by JDK-8202343
Message-ID: 

There are several infra test failures that were caused by the fix for JDK-8202343 (Disable TLS 1.0 and 1.1).

The problem is that test/jdk/javax/net/ssl/TLSCommon/interop/JdkProcClient.java is designed to be run with different versions of the JDK such as JDK 8 but now calls SecurityUtils.removeFromDisabledTlsAlgs() which calls APIs such as List.of() that are not available in JDK 8.

The fix is to create a private method which does the same thing as SecurityUtils.removeFromDisabledTlsAlgs() but doesn't depend on newer APIs.

-------------

Commit messages:
 - 8257083: Security infra test failures caused by JDK-8202343

Changes: https://git.openjdk.java.net/jdk/pull/1442/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1442&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8257083
  Stats: 24 lines in 1 file changed: 21 ins; 2 del; 1 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1442.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1442/head:pull/1442

PR: https://git.openjdk.java.net/jdk/pull/1442

From xuelei at openjdk.java.net  Wed Nov 25 20:35:59 2020
From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan)
Date: Wed, 25 Nov 2020 20:35:59 GMT
Subject: RFR: 8257083: Security infra test failures caused by JDK-8202343
In-Reply-To: 
References: 
Message-ID: 

On Wed, 25 Nov 2020 20:24:52 GMT, Sean Mullan  wrote:

> There are several infra test failures that were caused by the fix for JDK-8202343 (Disable TLS 1.0 and 1.1).
> 
> The problem is that test/jdk/javax/net/ssl/TLSCommon/interop/JdkProcClient.java is designed to be run with different versions of the JDK such as JDK 8 but now calls SecurityUtils.removeFromDisabledTlsAlgs() which calls APIs such as List.of() that are not available in JDK 8.
> 
> The fix is to create a private method which does the same thing as SecurityUtils.removeFromDisabledTlsAlgs() but doesn't depend on newer APIs.

Marked as reviewed by xuelei (Reviewer).

-------------

PR: https://git.openjdk.java.net/jdk/pull/1442

From github.com+828220+forax at openjdk.java.net  Wed Nov 25 20:43:01 2020
From: github.com+828220+forax at openjdk.java.net (=?UTF-8?B?UsOpbWk=?= Forax)
Date: Wed, 25 Nov 2020 20:43:01 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
 
 <4scjt1TdYV9Z6bN6YheIELaKERWLpvqE_fyR9bMNPEE=.c986e3d1-6a62-42c2-b087-4e7d47850ffb@github.com>
 
Message-ID: 

On Wed, 25 Nov 2020 19:48:32 GMT, Jim Laskey  wrote:

>> At least, it's more clear that it's reversed, i've initially miss the fact that f and g are swapped.
>> And :: is able to do inference so, i believe it can be written
>>   `.sorted(Comparator.comparingInt(RandomGeneratorFactory::stateBits).reversed())`
>
> Unfortunately it couldn't be inferred

It's because you have added reverse() as a postfix operation so the inference can not flow backward as it should,
using Collections.reverseOrder() should fix that
`.sorted(Collections.reverseOrder(Comparator.comparingInt(RandomGeneratorFactory::stateBits)))`

using some import statics for reverseOrder and comparintInt make the code readable but given it's in the doc, we are out of luck here.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From ascarpino at openjdk.java.net  Thu Nov 26 02:14:40 2020
From: ascarpino at openjdk.java.net (Anthony Scarpino)
Date: Thu, 26 Nov 2020 02:14:40 GMT
Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v5]
In-Reply-To: 
References: 
Message-ID: 

> 8253821: Improve ByteBuffer performance with GCM

Anthony Scarpino has updated the pull request incrementally with five additional commits since the last revision:

 - test updates
 - test check mixup
 - Overlap protection
 - Updated code comments, all tests pass
 - Updated code comments, all tests pass

-------------

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/411/files
  - new: https://git.openjdk.java.net/jdk/pull/411/files/8580c6ec..836bf3ed

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=411&range=04
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=411&range=03-04

  Stats: 745 lines in 6 files changed: 543 ins; 48 del; 154 mod
  Patch: https://git.openjdk.java.net/jdk/pull/411.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/411/head:pull/411

PR: https://git.openjdk.java.net/jdk/pull/411

From ascarpino at openjdk.java.net  Thu Nov 26 02:21:03 2020
From: ascarpino at openjdk.java.net (Anthony Scarpino)
Date: Thu, 26 Nov 2020 02:21:03 GMT
Subject: RFR: 8253821: Improve ByteBuffer performance with GCM [v5]
In-Reply-To: 
References: 
 <9IvsxvHGzvQoM756tUBFHLcMyZjvdbevzh7c-I3i6zU=.03c89dcb-a547-4a07-b0db-358fa9b3fe27@github.com>
 
 
Message-ID: 

On Thu, 12 Nov 2020 16:34:29 GMT, Anthony Scarpino  wrote:

>> This is an update for all of Valerie's comments and adding a test to verify different buffer types and configurations
>
> The latest update should address all outstanding comments.  The biggest change was to the test, which had major reorganization and created tests that increments data sizes for update and doFinal ops byte-by-byte to check for any errors.  That should reduce concerns about buffer corruption.

The biggest part of this change is the addition of overlap protection and the tests to verify it for GCM, as there were none in the open repo.  Additionally, GCMBufferTest had some significant changes to clean it up and handle offsets better.  All tests pass.  With RDP1 coming, I want to get this into the repo soon, so please limit comments to bugs. Any "nice to have" changes, they can be added onto follow-on changes I plan.

-------------

PR: https://git.openjdk.java.net/jdk/pull/411

From bradford.wetmore at oracle.com  Thu Nov 26 04:33:53 2020
From: bradford.wetmore at oracle.com (Bradford Wetmore)
Date: Wed, 25 Nov 2020 20:33:53 -0800
Subject: CSR-RFR: 8256817: Better support ALPN byte wire values in SunJSSE
Message-ID: <965b508c-17a2-f3cc-1d6e-fb3a0cbb1e28@oracle.com>

Hi Xuelei/Jamil/Tony/others(?),

I need a reviewer for this CSR, in preparation for:

     CSR:  https://bugs.openjdk.java.net/browse/JDK-8256817
     Bug:  https://bugs.openjdk.java.net/browse/JDK-8254631

     Draft Change:  https://github.com/openjdk/jdk/pull/1440

     8254631: Better support ALPN byte wire values in SunJSSE

It is the same approach as we have discussed internally, but after 
further analysis, I now consider the interoperability risk minimal due 
to a latent bug that was discovered during prototyping/testing.

I'd like to get this putback into JDK 16, so will need to be reviewed 
shortly after break to make the mid-December RDP1 deadline.

Thanks,

Brad

From jlaskey at openjdk.java.net  Thu Nov 26 15:36:03 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Thu, 26 Nov 2020 15:36:03 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 25 Nov 2020 14:10:17 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 497:
> 
>> 495:             ensureConstructors();
>> 496:             return ctorLong.newInstance(seed);
>> 497:         } catch (Exception ex) {
> 
> this one is very dubious because the result in an exception is thrown is a random generator with the wrong seed

This is explained in the docs.

> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 480:
> 
>> 478:         } catch (Exception ex) {
>> 479:             // Should never happen.
>> 480:             throw new IllegalStateException("Random algorithm " + name() + " is missing a default constructor");
> 
> chain the exception ...

agree

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Thu Nov 26 15:36:01 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Thu, 26 Nov 2020 15:36:01 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v5]
In-Reply-To: 
References: 
Message-ID: 

> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
> 
> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
> 
> old PR:  https://github.com/openjdk/jdk/pull/1273

Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:

  8248862: Implement Enhanced Pseudo-Random Number Generators
  
  Override AbstractSplittableGenerator

-------------

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/1292/files
  - new: https://git.openjdk.java.net/jdk/pull/1292/files/ee8f87c3..a6851940

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=04
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=03-04

  Stats: 165 lines in 3 files changed: 164 ins; 0 del; 1 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1292.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Thu Nov 26 15:44:01 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Thu, 26 Nov 2020 15:44:01 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v3]
In-Reply-To: 
References: 
 
 
Message-ID: 

On Wed, 25 Nov 2020 14:16:20 GMT, R?mi Forax  wrote:

>> Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:
>> 
>>   8248862: Implement Enhanced Pseudo-Random Number Generators
>>   
>>   Changes to RandomGeneratorFactory requested by @PaulSandoz
>
> src/java.base/share/classes/java/util/random/RandomGeneratorFactory.java line 46:
> 
>> 44: import java.util.stream.Stream;
>> 45: import jdk.internal.util.random.RandomSupport.RandomGeneratorProperty;
>> 46: 
> 
> Instead of calling a method properties to create a Map, it's usually far easier to use an annotation,
> annotation values supports less runtime type so BigInteger is not supported but using a String instead should be OK.

I kind of like the idea - not sure how expressive a BigInteger string is though. I might be able to express as   BigInteger.ONE.shiftLeft(i).subtract(j).shiftLeft(k). Will ponder.

-------------

PR: https://git.openjdk.java.net/jdk/pull/1292

From jlaskey at openjdk.java.net  Thu Nov 26 15:48:57 2020
From: jlaskey at openjdk.java.net (Jim Laskey)
Date: Thu, 26 Nov 2020 15:48:57 GMT
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
 [v6]
In-Reply-To: 
References: 
Message-ID: 

> This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 .
> 
> javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
> 
> old PR:  https://github.com/openjdk/jdk/pull/1273

Jim Laskey has updated the pull request incrementally with one additional commit since the last revision:

  8248862: Implement Enhanced Pseudo-Random Number Generators
  
  Propagate exception

-------------

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/1292/files
  - new: https://git.openjdk.java.net/jdk/pull/1292/files/a6851940..ca29ff74

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=05
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=04-05

  Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1292.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292

PR: https://git.openjdk.java.net/jdk/pull/1292

From wetmore at openjdk.java.net  Thu Nov 26 16:41:04 2020
From: wetmore at openjdk.java.net (Bradford Wetmore)
Date: Thu, 26 Nov 2020 16:41:04 GMT
Subject: RFR: 8220730: sun.security.provider.SecureRandom default constructor
 has wrong documentation
Message-ID: 

This is to fix some out-of-date information in the javadoc for the SHA1PRNG that has generated a customer bug.

-------------

Commit messages:
 - 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation

Changes: https://git.openjdk.java.net/jdk/pull/1461/files
 Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1461&range=00
  Issue: https://bugs.openjdk.java.net/browse/JDK-8220730
  Stats: 9 lines in 1 file changed: 4 ins; 0 del; 5 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1461.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1461/head:pull/1461

PR: https://git.openjdk.java.net/jdk/pull/1461

From forax at univ-mlv.fr  Sat Nov 21 12:03:59 2020
From: forax at univ-mlv.fr (Remi Forax)
Date: Sat, 21 Nov 2020 13:03:59 +0100 (CET)
Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators
In-Reply-To: 
References: 
Message-ID: <24865095.1772546.1605960239461.JavaMail.zimbra@u-pem.fr>

Ok, i've taking the time to read some literature about random generators because for me the Mersenne Twister was still the king.

The current API proposed as clearly two levels, you have the user level and the implementation level, at least the implementation level should seen as a SPI 

RandomGenerator is the user facing API, for me it should be the sole interface exposed by the API, the others (leap, arbitrary leap and split) should be optional methods.

In term of factory methods, we should have user driven methods:
- getDefaultGenerator() that currently returns a L64X128MixRandom and can be changed in the future
- getFastGenerator() that currently returns a Xoroshiro128PlusPlus and can be changed in the future
- getDefault[Splitable|Leapable|etc]Generator that returns a default generator with the methods splits|leaps|etc defined
- of / getByName that returns a specific generator by its name (but mov ed in a SPI class)

The example in the documentation should use getDefaultGenerator() and not of() to avoid the problem all the programming languages currently have by having over-specified that the default generator is a Mersenne Twister.

All methods that returns a stream of the available implementations should be moved in the SPI package.

R?mi 

---
An honest question,
why do we need so many interfaces for the different categories of RandomGenerator ?

My fear is that we are encoding the state of our knowledge of the different kinds of random generators now so it will not be pretty in the future when new categories of random generator are discovered/invented.
If we can take example of the past to predict the future, 20 years ago, what should have been the hierarchy at that time.
Is it not reasonable to think that we will need new kinds of random generator in the future ?

I wonder if it's not better to have one interface and several optional methods like we have with the collections, it means that we are loosing the possibilities to precisely type a method that only works with a precise type of generator but it will be more future proof.

R?mi

----- Mail original -----
> De: "Jim Laskey" 
> ?: "core-libs-dev" , "security-dev" 
> Envoy?: Mercredi 18 Novembre 2020 14:52:56
> Objet: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators

> This PR is to introduce a new random number API for the JDK. The primary API is
> found in RandomGenerator and RandomGeneratorFactory. Further description can be
> found in the JEP https://openjdk.java.net/jeps/356 .
> 
> javadoc can be found at
> http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html
> 
> old PR:  https://github.com/openjdk/jdk/pull/1273
> 
> -------------
> 
> Commit messages:
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862; Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - 8248862: Implement Enhanced Pseudo-Random Number Generators
> - ... and 15 more: https://git.openjdk.java.net/jdk/compare/f7517386...2b3e4ed7
> 
> Changes: https://git.openjdk.java.net/jdk/pull/1292/files
> Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=00
>  Issue: https://bugs.openjdk.java.net/browse/JDK-8248862
>  Stats: 13319 lines in 25 files changed: 11110 ins; 2132 del; 77 mod
>  Patch: https://git.openjdk.java.net/jdk/pull/1292.diff
>  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292
> 
> PR: https://git.openjdk.java.net/jdk/pull/1292

From wetmore at openjdk.java.net  Thu Nov 26 16:59:11 2020
From: wetmore at openjdk.java.net (Bradford Wetmore)
Date: Thu, 26 Nov 2020 16:59:11 GMT
Subject: RFR: 8220730: sun.security.provider.SecureRandom default
 constructor has wrong documentation [v2]
In-Reply-To: 
References: 
Message-ID: 

> This is to fix some out-of-date information in the javadoc for the SHA1PRNG that has generated a customer bug.

Bradford Wetmore has updated the pull request incrementally with one additional commit since the last revision:

  Minor grammar error

-------------

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/1461/files
  - new: https://git.openjdk.java.net/jdk/pull/1461/files/bc4b6757..92637075

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1461&range=01
 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1461&range=00-01

  Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod
  Patch: https://git.openjdk.java.net/jdk/pull/1461.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/1461/head:pull/1461

PR: https://git.openjdk.java.net/jdk/pull/1461

From weijun at openjdk.java.net  Thu Nov 26 17:44:58 2020
From: weijun at openjdk.java.net (Weijun Wang)
Date: Thu, 26 Nov 2020 17:44:58 GMT
Subject: RFR: 8220730: sun.security.provider.SecureRandom default
 constructor has wrong documentation [v2]
In-Reply-To: 
References: 
 
Message-ID: 

On Thu, 26 Nov 2020 16:59:11 GMT, Bradford Wetmore  wrote:

>> This is to fix some out-of-date information in the javadoc for the SHA1PRNG that has generated a customer bug.
>
> Bradford Wetmore has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Minor grammar error

I feel some sentences are still not precise.

src/java.base/share/classes/sun/security/provider/SecureRandom.java line 68:

> 66: 
> 67:     /**
> 68:      * This empty constructor.

How about "An empty constructor that creates an unseeded SecureRandom object"?

src/java.base/share/classes/sun/security/provider/SecureRandom.java line 78:

> 76:      *
> 77:      * 

The first time this constructor is called in a given Virtual Machine, > 78: * it may take several seconds of CPU time to seed the generator, depending In my understanding this is not true. The constructor will finish in no time, it's the first engineBytes() call that will take several seconds. We may say "this auto seeding process will...". ------------- PR: https://git.openjdk.java.net/jdk/pull/1461 From wetmore at openjdk.java.net Thu Nov 26 18:00:06 2020 From: wetmore at openjdk.java.net (Bradford Wetmore) Date: Thu, 26 Nov 2020 18:00:06 GMT Subject: RFR: 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation [v2] In-Reply-To: References: Message-ID: <_QgIpNeUuWrfI27hhzADsbu16MstVkR4SuwWYhLZguY=.0601cf70-592e-4608-9aa9-263fc16905a8@github.com> On Thu, 26 Nov 2020 17:41:23 GMT, Weijun Wang wrote: >> Bradford Wetmore has updated the pull request incrementally with one additional commit since the last revision: >> >> Minor grammar error > > src/java.base/share/classes/sun/security/provider/SecureRandom.java line 78: > >> 76: * >> 77: *

The first time this constructor is called in a given Virtual Machine, >> 78: * it may take several seconds of CPU time to seed the generator, depending > > In my understanding this is not true. The constructor will finish in no time, it's the first engineBytes() call that will take several seconds. We may say "this auto seeding process will...". Are you talking about the line 78? Yes, you are correct, I didn't update anything beyond the initial comment. I can update that as well. > src/java.base/share/classes/sun/security/provider/SecureRandom.java line 68: > >> 66: >> 67: /** >> 68: * This empty constructor. > > How about "An empty constructor that creates an unseeded SecureRandom object"? Sure, that sounds great. ------------- PR: https://git.openjdk.java.net/jdk/pull/1461 From weijun at openjdk.java.net Thu Nov 26 18:00:07 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Thu, 26 Nov 2020 18:00:07 GMT Subject: RFR: 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation [v2] In-Reply-To: <_QgIpNeUuWrfI27hhzADsbu16MstVkR4SuwWYhLZguY=.0601cf70-592e-4608-9aa9-263fc16905a8@github.com> References: <_QgIpNeUuWrfI27hhzADsbu16MstVkR4SuwWYhLZguY=.0601cf70-592e-4608-9aa9-263fc16905a8@github.com> Message-ID: On Thu, 26 Nov 2020 17:55:06 GMT, Bradford Wetmore wrote: >> src/java.base/share/classes/sun/security/provider/SecureRandom.java line 78: >> >>> 76: * >>> 77: *

The first time this constructor is called in a given Virtual Machine, >>> 78: * it may take several seconds of CPU time to seed the generator, depending >> >> In my understanding this is not true. The constructor will finish in no time, it's the first engineBytes() call that will take several seconds. We may say "this auto seeding process will...". > > Are you talking about the line 78? Yes, you are correct, I didn't update anything beyond the initial comment. I can update that as well. Yes, the paragraph starting from line 77. ------------- PR: https://git.openjdk.java.net/jdk/pull/1461 From jlaskey at openjdk.java.net Thu Nov 26 18:19:02 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Thu, 26 Nov 2020 18:19:02 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v7] In-Reply-To: References: Message-ID: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html > > old PR: https://github.com/openjdk/jdk/pull/1273 Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: 8248862: Implement Enhanced Pseudo-Random Number Generators Cleanups from Chris H. ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1292/files - new: https://git.openjdk.java.net/jdk/pull/1292/files/ca29ff74..a8cc0795 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=06 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=05-06 Stats: 13 lines in 1 file changed: 4 ins; 3 del; 6 mod Patch: https://git.openjdk.java.net/jdk/pull/1292.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292 PR: https://git.openjdk.java.net/jdk/pull/1292 From wetmore at openjdk.java.net Thu Nov 26 18:38:13 2020 From: wetmore at openjdk.java.net (Bradford Wetmore) Date: Thu, 26 Nov 2020 18:38:13 GMT Subject: RFR: 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation [v3] In-Reply-To: References: Message-ID: > This is to fix some out-of-date information in the javadoc for the SHA1PRNG that has generated a customer bug. Bradford Wetmore has updated the pull request incrementally with one additional commit since the last revision: Code review comments ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1461/files - new: https://git.openjdk.java.net/jdk/pull/1461/files/92637075..d7949a8f Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1461&range=02 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1461&range=01-02 Stats: 14 lines in 1 file changed: 1 ins; 0 del; 13 mod Patch: https://git.openjdk.java.net/jdk/pull/1461.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1461/head:pull/1461 PR: https://git.openjdk.java.net/jdk/pull/1461 From weijun at openjdk.java.net Thu Nov 26 18:38:14 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Thu, 26 Nov 2020 18:38:14 GMT Subject: RFR: 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation [v3] In-Reply-To: References: Message-ID: On Thu, 26 Nov 2020 18:33:15 GMT, Bradford Wetmore wrote: >> This is to fix some out-of-date information in the javadoc for the SHA1PRNG that has generated a customer bug. > > Bradford Wetmore has updated the pull request incrementally with one additional commit since the last revision: > > Code review comments Looks fine. Thanks. ------------- Marked as reviewed by weijun (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/1461 From wetmore at openjdk.java.net Thu Nov 26 18:44:58 2020 From: wetmore at openjdk.java.net (Bradford Wetmore) Date: Thu, 26 Nov 2020 18:44:58 GMT Subject: RFR: 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation [v2] In-Reply-To: References: <_QgIpNeUuWrfI27hhzADsbu16MstVkR4SuwWYhLZguY=.0601cf70-592e-4608-9aa9-263fc16905a8@github.com> Message-ID: On Thu, 26 Nov 2020 17:57:03 GMT, Weijun Wang wrote: >> Are you talking about the line 78? Yes, you are correct, I didn't update anything beyond the initial comment. I can update that as well. > > Yes, the paragraph starting from line 77. Got it, thanks for the reviews. ------------- PR: https://git.openjdk.java.net/jdk/pull/1461 From wetmore at openjdk.java.net Thu Nov 26 18:50:54 2020 From: wetmore at openjdk.java.net (Bradford Wetmore) Date: Thu, 26 Nov 2020 18:50:54 GMT Subject: Integrated: 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation In-Reply-To: References: Message-ID: <4z5DVedgc04AK70ujRRYpMkcGeIuAnSfip16ZYba_tc=.912c3cae-5462-4749-871b-d72d94d4d90e@github.com> On Thu, 26 Nov 2020 16:34:53 GMT, Bradford Wetmore wrote: > This is to fix some out-of-date information in the javadoc for the SHA1PRNG that has generated a customer bug. This pull request has now been integrated. Changeset: 62d72dec Author: Bradford Wetmore URL: https://git.openjdk.java.net/jdk/commit/62d72dec Stats: 16 lines in 1 file changed: 5 ins; 0 del; 11 mod 8220730: sun.security.provider.SecureRandom default constructor has wrong documentation Reviewed-by: weijun ------------- PR: https://git.openjdk.java.net/jdk/pull/1461 From jlaskey at openjdk.java.net Fri Nov 27 15:03:04 2020 From: jlaskey at openjdk.java.net (Jim Laskey) Date: Fri, 27 Nov 2020 15:03:04 GMT Subject: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v8] In-Reply-To: References: Message-ID: > This PR is to introduce a new random number API for the JDK. The primary API is found in RandomGenerator and RandomGeneratorFactory. Further description can be found in the JEP https://openjdk.java.net/jeps/356 . > > javadoc can be found at http://cr.openjdk.java.net/~jlaskey/prng/doc/api/java.base/java/util/random/package-summary.html > > old PR: https://github.com/openjdk/jdk/pull/1273 Jim Laskey has updated the pull request incrementally with one additional commit since the last revision: 8248862: Implement Enhanced Pseudo-Random Number Generators Added coverage testing ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1292/files - new: https://git.openjdk.java.net/jdk/pull/1292/files/a8cc0795..f7b697ec Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=07 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1292&range=06-07 Stats: 168 lines in 3 files changed: 166 ins; 2 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/1292.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1292/head:pull/1292 PR: https://git.openjdk.java.net/jdk/pull/1292 From clanger at openjdk.java.net Fri Nov 27 15:48:54 2020 From: clanger at openjdk.java.net (Christoph Langer) Date: Fri, 27 Nov 2020 15:48:54 GMT Subject: RFR: 8256818: SSLSocket that is never bound or connected leaks socket resources In-Reply-To: References: Message-ID: On Sat, 21 Nov 2020 23:21:15 GMT, Christoph Langer wrote: >> There is a flaw in sun.security.ssl.SSLSocketImpl::close() which leads to leaking socket resources after JDK-8224829. >> >> The close method calls duplexCloseOutput() and duplexCloseInput(). In case of an exception in any of these methods, the call to closeSocket() is bypassed, and the underlying Socket may not be closed. >> >> This manifests in a real life leak after JDK-8224829 has introduced a call to getSoLinger() on the path of duplexCloseOutput -> closeNotify. If socket impl / OS socket hadn't been created yet it is done at that place. But then after duplexCloseOutput eventually fails with a SocketException since the socket wasn't connected, closing fails to call Socket::close(). >> >> This problem can be reproduced by this code: >> SSLSocket sslSocket = (SSLSocket)SSLSocketFactory.getDefault().createSocket(); >> sslSocket.getSSLParameters(); >> sslSocket.close(); >> >> This is what happens when SSLContext.getDefault().getDefaultSSLParameters() is called, with close() being eventually called by the finalizer. >> >> I'll open this PR as draft for now to start discussion. I'll create a testcase to reproduce the issue and add it soon. >> >> I propose to modify the close method such that duplexClose is only done on a connected/bound socket. Maybe it even suffices to only do it when connected. >> >> Secondly, I'm proposing to improve exception handling a bit. So in case there's an IOException on the path of duplexClose, it is caught and logged. But the real close moves to the finally block since it should be done unconditionally. > > I changed the check for when to do duplexClose to only do it when socket isConnected(). > > I also added a testcase which should work on all platforms. For windows I borrowed some functionality introduced lately with test java/lang/ProcessBuilder/checkHandles/CheckHandles.java which I moved to the test library for that reason. > > Now it's ready to review. Ping... Any takers? comments? reviews? ------------- PR: https://git.openjdk.java.net/jdk/pull/1363 From xuelei at openjdk.java.net Fri Nov 27 16:17:55 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Fri, 27 Nov 2020 16:17:55 GMT Subject: RFR: 8256818: SSLSocket that is never bound or connected leaks socket resources In-Reply-To: References: Message-ID: On Fri, 27 Nov 2020 15:46:08 GMT, Christoph Langer wrote: >> I changed the check for when to do duplexClose to only do it when socket isConnected(). >> >> I also added a testcase which should work on all platforms. For windows I borrowed some functionality introduced lately with test java/lang/ProcessBuilder/checkHandles/CheckHandles.java which I moved to the test library for that reason. >> >> Now it's ready to review. > > Ping... Any takers? comments? reviews? I will have a look at this update. ------------- PR: https://git.openjdk.java.net/jdk/pull/1363 From weijun at openjdk.java.net Fri Nov 27 19:46:01 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Fri, 27 Nov 2020 19:46:01 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 Message-ID: There should only be one curve having type BD or PD in CurveDB.java for any given length. Here we keep the last one (sect163r2) so there's no behavior change. I tried to search on the net to see if there is a consensus on which curve is meant to be the default one for a size, but cannot find one for 163. If anyone can find it I'll be happy to take a look. Noreg-cleanup. ------------- Commit messages: - 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 Changes: https://git.openjdk.java.net/jdk/pull/1485/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1485&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8213719 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/1485.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1485/head:pull/1485 PR: https://git.openjdk.java.net/jdk/pull/1485 From xuelei at openjdk.java.net Sun Nov 29 20:37:00 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Sun, 29 Nov 2020 20:37:00 GMT Subject: RFR: JDK-8257237: Cleanup unused imports in the SunJSSE provider implementation Message-ID: This change cleanups the unused imports in the SunJSSE provider implementation. Cleanup only, no new regression test. Bug: https://bugs.openjdk.java.net/browse/JDK-8257237 ------------- Commit messages: - cleanup unused imports in the SunJSSE provider implementation Changes: https://git.openjdk.java.net/jdk/pull/1508/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1508&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8257237 Stats: 6 lines in 3 files changed: 0 ins; 5 del; 1 mod Patch: https://git.openjdk.java.net/jdk/pull/1508.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1508/head:pull/1508 PR: https://git.openjdk.java.net/jdk/pull/1508 From wetmore at openjdk.java.net Mon Nov 30 01:41:54 2020 From: wetmore at openjdk.java.net (Bradford Wetmore) Date: Mon, 30 Nov 2020 01:41:54 GMT Subject: RFR: JDK-8257237: Cleanup unused imports in the SunJSSE provider implementation In-Reply-To: References: Message-ID: On Sun, 29 Nov 2020 20:29:42 GMT, Xue-Lei Andrew Fan wrote: > This change cleanups the unused imports in the SunJSSE provider implementation. Cleanup only, no new regression test. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8257237 Looks good. ------------- Marked as reviewed by wetmore (Reviewer). PR: https://git.openjdk.java.net/jdk/pull/1508 From xuelei at openjdk.java.net Mon Nov 30 01:57:56 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Mon, 30 Nov 2020 01:57:56 GMT Subject: Integrated: JDK-8257237: Cleanup unused imports in the SunJSSE provider implementation In-Reply-To: References: Message-ID: On Sun, 29 Nov 2020 20:29:42 GMT, Xue-Lei Andrew Fan wrote: > This change cleanups the unused imports in the SunJSSE provider implementation. Cleanup only, no new regression test. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8257237 This pull request has now been integrated. Changeset: fdee70d1 Author: Xue-Lei Andrew Fan URL: https://git.openjdk.java.net/jdk/commit/fdee70d1 Stats: 6 lines in 3 files changed: 0 ins; 5 del; 1 mod 8257237: Cleanup unused imports in the SunJSSE provider implementation Reviewed-by: wetmore ------------- PR: https://git.openjdk.java.net/jdk/pull/1508 From github.com+27751938+amcap1712 at openjdk.java.net Mon Nov 30 12:53:02 2020 From: github.com+27751938+amcap1712 at openjdk.java.net (Kartik Ohri) Date: Mon, 30 Nov 2020 12:53:02 GMT Subject: RFR: JDK-8257401: Use switch expressions in jdk.internal.net.http and java.net.http Message-ID: Hi! Kindly review this patch to replace switch statements with switch expressions (where it makes sense) in the http client modules. The rationale is to improve readability of the code. Regards, Kartik ------------- Commit messages: - Use switch expressions in jdk.internal.net.http and java.net.http Changes: https://git.openjdk.java.net/jdk/pull/1364/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1364&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8257401 Stats: 270 lines in 17 files changed: 1 ins; 137 del; 132 mod Patch: https://git.openjdk.java.net/jdk/pull/1364.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1364/head:pull/1364 PR: https://git.openjdk.java.net/jdk/pull/1364 From github.com+27751938+amcap1712 at openjdk.java.net Mon Nov 30 13:04:11 2020 From: github.com+27751938+amcap1712 at openjdk.java.net (Kartik Ohri) Date: Mon, 30 Nov 2020 13:04:11 GMT Subject: RFR: JDK-8257401: Use switch expressions in jdk.internal.net.http and java.net.http [v2] In-Reply-To: References: Message-ID: > Hi! > Kindly review this patch to replace switch statements with switch expressions (where it makes sense) in the http client modules. The rationale is to improve readability of the code. > Regards, > Kartik Kartik Ohri has refreshed the contents of this pull request, and previous commits have been removed. The incremental views will show differences compared to the previous content of the PR. The pull request contains one new commit since the last revision: JDK-8257401: Use switch expressions in jdk.internal.net.http and java.net.http ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1364/files - new: https://git.openjdk.java.net/jdk/pull/1364/files/4ecf4e0d..542298e0 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1364&range=01 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1364&range=00-01 Stats: 0 lines in 0 files changed: 0 ins; 0 del; 0 mod Patch: https://git.openjdk.java.net/jdk/pull/1364.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1364/head:pull/1364 PR: https://git.openjdk.java.net/jdk/pull/1364 From mullan at openjdk.java.net Mon Nov 30 13:34:56 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 30 Nov 2020 13:34:56 GMT Subject: Integrated: 8257083: Security infra test failures caused by JDK-8202343 In-Reply-To: References: Message-ID: On Wed, 25 Nov 2020 20:24:52 GMT, Sean Mullan wrote: > There are several infra test failures that were caused by the fix for JDK-8202343 (Disable TLS 1.0 and 1.1). > > The problem is that test/jdk/javax/net/ssl/TLSCommon/interop/JdkProcClient.java is designed to be run with different versions of the JDK such as JDK 8 but now calls SecurityUtils.removeFromDisabledTlsAlgs() which calls APIs such as List.of() that are not available in JDK 8. > > The fix is to create a private method which does the same thing as SecurityUtils.removeFromDisabledTlsAlgs() but doesn't depend on newer APIs. This pull request has now been integrated. Changeset: c0719605 Author: Sean Mullan URL: https://git.openjdk.java.net/jdk/commit/c0719605 Stats: 24 lines in 1 file changed: 21 ins; 2 del; 1 mod 8257083: Security infra test failures caused by JDK-8202343 Reviewed-by: xuelei ------------- PR: https://git.openjdk.java.net/jdk/pull/1442 From valeriep at openjdk.java.net Mon Nov 30 18:36:55 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 30 Nov 2020 18:36:55 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Fri, 27 Nov 2020 19:40:35 GMT, Weijun Wang wrote: > There should only be one curve having type BD or PD in CurveDB.java for any given length. Here we keep the last one (sect163r2) so there's no behavior change. > > I tried to search on the net to see if there is a consensus on which curve is meant to be the default one for a size, but cannot find one for 163. If anyone can find it I'll be happy to take a look. > Based on CurveDB line 141, it seems we uses the first one and discards the rest? Are you sure we keep the last one? Don't have answers for your questions though. ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From xuelei at openjdk.java.net Mon Nov 30 19:57:03 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Mon, 30 Nov 2020 19:57:03 GMT Subject: RFR: JDK-8257448: Clean duplicated non-null check in the SunJSSE provider implementation Message-ID: In the SunJSSE provider implementation, there are a few non-null check, used together with "instanceof" check. For such cases, the non-null check is redundant as it could be covered by the "instanceof" check. This update will remove the non-null check, like: - if ((cause != null) && (cause instanceof IOException)) { + if (cause instanceof IOException) { Code cleanup, no new regression text. Bug: https://bugs.openjdk.java.net/browse/JDK-8257448 ------------- Commit messages: - 8257448: Clean duplicated non-null check Changes: https://git.openjdk.java.net/jdk/pull/1524/files Webrev: https://webrevs.openjdk.java.net/?repo=jdk&pr=1524&range=00 Issue: https://bugs.openjdk.java.net/browse/JDK-8257448 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod Patch: https://git.openjdk.java.net/jdk/pull/1524.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1524/head:pull/1524 PR: https://git.openjdk.java.net/jdk/pull/1524 From jnimeh at openjdk.java.net Mon Nov 30 20:40:27 2020 From: jnimeh at openjdk.java.net (Jamil Nimeh) Date: Mon, 30 Nov 2020 20:40:27 GMT Subject: RFR: JDK-8166596: TLS support for the EdDSA signature algorithm [v4] In-Reply-To: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> References: <494dyYv2GdCxfYFY_sWHiggwJDfTmt5yYAXLil4peLI=.6c49d2f4-4036-4a24-a671-e50cef636fd4@github.com> Message-ID: > Hello all, > This change brings in support for certificates with EdDSA keys (both Ed25519 and Ed448) allowing those signature algorithms to be used both on the certificates themselves and used during the handshaking process for messages like CertificateVerify, ServerKeyExchange and so forth. Jamil Nimeh has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains eight additional commits since the last revision: - Merge - Update test to account for JDK-8202343 fix - Merge - Merge - Applied code review comments to tests - Fix cut/paste error with ECDH-RSA key exchange - Merge - Initial EdDSA/TLS solution ------------- Changes: - all: https://git.openjdk.java.net/jdk/pull/1197/files - new: https://git.openjdk.java.net/jdk/pull/1197/files/dee70944..58651fc5 Webrevs: - full: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=03 - incr: https://webrevs.openjdk.java.net/?repo=jdk&pr=1197&range=02-03 Stats: 192313 lines in 1163 files changed: 125674 ins; 47707 del; 18932 mod Patch: https://git.openjdk.java.net/jdk/pull/1197.diff Fetch: git fetch https://git.openjdk.java.net/jdk pull/1197/head:pull/1197 PR: https://git.openjdk.java.net/jdk/pull/1197 From weijun at openjdk.java.net Mon Nov 30 20:44:55 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 30 Nov 2020 20:44:55 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Mon, 30 Nov 2020 18:34:40 GMT, Valerie Peng wrote: > Based on CurveDB line 141, it seems we uses the first one and discards the rest? Are you sure we keep the last one? > Don't have answers for your questions though. Before this change both sect163k1 and sect163r2 have "BD" so both will be added to lengthMap and the 2nd one wins out. ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From mullan at openjdk.java.net Mon Nov 30 20:50:55 2020 From: mullan at openjdk.java.net (Sean Mullan) Date: Mon, 30 Nov 2020 20:50:55 GMT Subject: RFR: JDK-8257448: Clean duplicated non-null check in the SunJSSE provider implementation In-Reply-To: References: Message-ID: <71mjtGV-rBgBotKmOOVhnKQJJAse3uFJKD5MP3HgUME=.b56de40b-6a34-4cbd-9a35-3c2e6b45f2f9@github.com> On Mon, 30 Nov 2020 19:51:42 GMT, Xue-Lei Andrew Fan wrote: > In the SunJSSE provider implementation, there are a few non-null check, used together with "instanceof" check. For such cases, the non-null check is redundant as it could be covered by the "instanceof" check. This update will remove the non-null check, like: > - if ((cause != null) && (cause instanceof IOException)) { > + if (cause instanceof IOException) { > > Code cleanup, no new regression text. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8257448 Marked as reviewed by mullan (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1524 From valeriep at openjdk.java.net Mon Nov 30 21:10:01 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 30 Nov 2020 21:10:01 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Mon, 30 Nov 2020 20:42:35 GMT, Weijun Wang wrote: > > > > Based on CurveDB line 141, it seems we uses the first one and discards the rest? Are you sure we keep the last one? > > Don't have answers for your questions though. > > Before this change both sect163k1 and sect163r2 have "BD" so both will be added to lengthMap and the 2nd one wins out. Hmm, ok, I re-read the code and it's true that both are added to the lengthMap. Actually, non-PD/non-BD entries are added to the length map too if no entries for such length in length map is present at time of the add() call, right? ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From weijun at openjdk.java.net Mon Nov 30 21:33:57 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 30 Nov 2020 21:33:57 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Mon, 30 Nov 2020 21:07:03 GMT, Valerie Peng wrote: > > > Based on CurveDB line 141, it seems we uses the first one and discards the rest? Are you sure we keep the last one? > > > Don't have answers for your questions though. > > > > > > Before this change both sect163k1 and sect163r2 have "BD" so both will be added to lengthMap and the 2nd one wins out. > > Hmm, ok, I re-read the code and it's true that both are added to the lengthMap. Actually, non-PD/non-BD entries are added to the length map too if no entries for such length in length map is present at time of the add() call, right? Yes, I think that's what "if there are multiple matches for the given size, an arbitrary one is returns" in the comment of `lookup(int)` means. If there is a PD/BD with the same length, the previously added will be substituted anyway. ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From valeriep at openjdk.java.net Mon Nov 30 21:49:58 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 30 Nov 2020 21:49:58 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Fri, 27 Nov 2020 19:40:35 GMT, Weijun Wang wrote: > There should only be one curve having type BD or PD in CurveDB.java for any given length. Here we keep the last one (sect163r2) so there's no behavior change. > > I tried to search on the net to see if there is a consensus on which curve is meant to be the default one for a size, but cannot find one for 163. If anyone can find it I'll be happy to take a look. > > Noreg-cleanup. Marked as reviewed by valeriep (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From valeriep at openjdk.java.net Mon Nov 30 21:49:59 2020 From: valeriep at openjdk.java.net (Valerie Peng) Date: Mon, 30 Nov 2020 21:49:59 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: <3_WKxGcm7wZ2BiBzmNB0NKouNiWMDrFC1PGuShausSo=.8d029bb6-13f6-46cf-9407-3854501c4f83@github.com> On Mon, 30 Nov 2020 21:31:18 GMT, Weijun Wang wrote: >>> >>> >>> > Based on CurveDB line 141, it seems we uses the first one and discards the rest? Are you sure we keep the last one? >>> > Don't have answers for your questions though. >>> >>> Before this change both sect163k1 and sect163r2 have "BD" so both will be added to lengthMap and the 2nd one wins out. >> >> Hmm, ok, I re-read the code and it's true that both are added to the lengthMap. Actually, non-PD/non-BD entries are added to the length map too if no entries for such length in length map is present at time of the add() call, right? > >> > > Based on CurveDB line 141, it seems we uses the first one and discards the rest? Are you sure we keep the last one? >> > > Don't have answers for your questions though. >> > >> > >> > Before this change both sect163k1 and sect163r2 have "BD" so both will be added to lengthMap and the 2nd one wins out. >> >> Hmm, ok, I re-read the code and it's true that both are added to the lengthMap. Actually, non-PD/non-BD entries are added to the length map too if no entries for such length in length map is present at time of the add() call, right? > > Yes, I think that's what "if there are multiple matches for the given size, an arbitrary one is returns" in the comment of `lookup(int)` means. If there is a PD/BD with the same length, the previously added will be substituted anyway. Alright, I have no more comments/questions. Thanks. ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From xuelei at openjdk.java.net Mon Nov 30 22:00:58 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Mon, 30 Nov 2020 22:00:58 GMT Subject: Integrated: JDK-8257448: Clean duplicated non-null check in the SunJSSE provider implementation In-Reply-To: References: Message-ID: <3-O4YiMrWeUAh72MUdGBi_zJ9VY1rZughdc8DmJGpN4=.e78786c3-47ac-4bf3-b4d2-71d9c0d8994c@github.com> On Mon, 30 Nov 2020 19:51:42 GMT, Xue-Lei Andrew Fan wrote: > In the SunJSSE provider implementation, there are a few non-null check, used together with "instanceof" check. For such cases, the non-null check is redundant as it could be covered by the "instanceof" check. This update will remove the non-null check, like: > - if ((cause != null) && (cause instanceof IOException)) { > + if (cause instanceof IOException) { > > Code cleanup, no new regression text. > > Bug: https://bugs.openjdk.java.net/browse/JDK-8257448 This pull request has now been integrated. Changeset: ae5b5268 Author: Xue-Lei Andrew Fan URL: https://git.openjdk.java.net/jdk/commit/ae5b5268 Stats: 2 lines in 2 files changed: 0 ins; 0 del; 2 mod 8257448: Clean duplicated non-null check in the SunJSSE provider implementation Reviewed-by: mullan ------------- PR: https://git.openjdk.java.net/jdk/pull/1524 From xuelei at openjdk.java.net Mon Nov 30 22:22:57 2020 From: xuelei at openjdk.java.net (Xue-Lei Andrew Fan) Date: Mon, 30 Nov 2020 22:22:57 GMT Subject: RFR: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Fri, 27 Nov 2020 19:40:35 GMT, Weijun Wang wrote: > There should only be one curve having type BD or PD in CurveDB.java for any given length. Here we keep the last one (sect163r2) so there's no behavior change. > > I tried to search on the net to see if there is a consensus on which curve is meant to be the default one for a size, but cannot find one for 163. If anyone can find it I'll be happy to take a look. > > Noreg-cleanup. Marked as reviewed by xuelei (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/1485 From weijun at openjdk.java.net Mon Nov 30 22:22:57 2020 From: weijun at openjdk.java.net (Weijun Wang) Date: Mon, 30 Nov 2020 22:22:57 GMT Subject: Integrated: 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 In-Reply-To: References: Message-ID: On Fri, 27 Nov 2020 19:40:35 GMT, Weijun Wang wrote: > There should only be one curve having type BD or PD in CurveDB.java for any given length. Here we keep the last one (sect163r2) so there's no behavior change. > > I tried to search on the net to see if there is a consensus on which curve is meant to be the default one for a size, but cannot find one for 163. If anyone can find it I'll be happy to take a look. > > Noreg-cleanup. This pull request has now been integrated. Changeset: 7f58a8e9 Author: Weijun Wang URL: https://git.openjdk.java.net/jdk/commit/7f58a8e9 Stats: 1 line in 1 file changed: 0 ins; 0 del; 1 mod 8213719: Both sect163r2 and sect163k1 are default curves for field size 163 Reviewed-by: valeriep, xuelei ------------- PR: https://git.openjdk.java.net/jdk/pull/1485