Re: RFR: JDK-8266670: Better modeling of access flags in core reflection [v20]

2022-05-31 Thread Rémi Forax
On Wed, 25 May 2022 00:35:24 GMT, Joe Darcy  wrote:

>> This is an early review of changes to better model JVM access flags, that is 
>> "modifiers" like public, protected, etc. but explicitly at a VM level.
>> 
>> Language level modifiers and JVM level access flags are closely related, but 
>> distinct. There are concepts that overlap in the two domains (public, 
>> private, etc.), others that only have a language-level modifier (sealed), 
>> and still others that only have an access flag (synthetic).
>> 
>> The existing java.lang.reflect.Modifier class is inadequate to model these 
>> subtleties. For example, the bit positions used by access flags on different 
>> kinds of elements overlap (such as "volatile" for fields and "bridge" for 
>> methods. Just having a raw integer does not provide sufficient context to 
>> decode the corresponding language-level string. Methods like 
>> Modifier.methodModifiers() were introduced to cope with this situation.
>> 
>> With additional modifiers and flags on the horizon with projects like 
>> Valhalla, addressing the existent modeling deficiency now ahead of time is 
>> reasonable before further strain is introduced.
>> 
>> This PR in its current form is meant to give the overall shape of the API. 
>> It is missing implementations to map from, say, method modifiers to access 
>> flags, taking into account overlaps in bit positions.
>> 
>> The CSR https://bugs.openjdk.java.net/browse/JDK-8281660 will be filled in 
>> once the API is further along.
>
> Joe Darcy 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 32 additional commits since 
> the last revision:
> 
>  - Target JDK 20 rather than 19.
>  - Merge branch 'master' into JDK-8266670
>  - Add mask values to constants' javadoc.
>  - Implement review feedback from mlchung.
>  - Fix type in @throws tag.
>  - Merge branch 'master' into JDK-8266670
>  - Respond to review feedback.
>  - Merge branch 'master' into JDK-8266670
>  - Make workding changes suggested in review feedback.
>  - Merge branch 'master' into JDK-8266670
>  - ... and 22 more: 
> https://git.openjdk.java.net/jdk/compare/74cd2687...05cf2d8b

src/java.base/share/classes/java/lang/reflect/Member.java line 96:

> 94:  */
> 95: public default Set accessFlags() {
> 96: return Set.of();

Is is not better to throw a NoSuchMethodError instead of Set.of() if there is 
no implementation.

-

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


Re: RFR: JDK-8266670: Better modeling of access flags in core reflection [v4]

2022-05-31 Thread Rémi Forax
On Tue, 15 Feb 2022 21:05:08 GMT, Joe Darcy  wrote:

>> Note that the presence or absence of `ACC_SUPER` has no effect since **Java 
>> 8**, which always treats it as set regardless of the actual contents of the 
>> binary class file.
>
> For completeness, I think including SUPER is reasonable, even though has been 
> a no-op for some time. (Some time in the future, there could be a class file 
> version aware additions to this enum class.) Well spotted omission.

`ACC_SUPER`may be reconed as `ACC_IDENTITY`by Valhalla, so i'm not sure it's a 
good idea to add ACC_SUPER.

-

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


Re: RFR: JDK-8266670: Better modeling of access flags in core reflection [v20]

2022-05-31 Thread Rémi Forax
On Wed, 25 May 2022 00:35:24 GMT, Joe Darcy  wrote:

>> This is an early review of changes to better model JVM access flags, that is 
>> "modifiers" like public, protected, etc. but explicitly at a VM level.
>> 
>> Language level modifiers and JVM level access flags are closely related, but 
>> distinct. There are concepts that overlap in the two domains (public, 
>> private, etc.), others that only have a language-level modifier (sealed), 
>> and still others that only have an access flag (synthetic).
>> 
>> The existing java.lang.reflect.Modifier class is inadequate to model these 
>> subtleties. For example, the bit positions used by access flags on different 
>> kinds of elements overlap (such as "volatile" for fields and "bridge" for 
>> methods. Just having a raw integer does not provide sufficient context to 
>> decode the corresponding language-level string. Methods like 
>> Modifier.methodModifiers() were introduced to cope with this situation.
>> 
>> With additional modifiers and flags on the horizon with projects like 
>> Valhalla, addressing the existent modeling deficiency now ahead of time is 
>> reasonable before further strain is introduced.
>> 
>> This PR in its current form is meant to give the overall shape of the API. 
>> It is missing implementations to map from, say, method modifiers to access 
>> flags, taking into account overlaps in bit positions.
>> 
>> The CSR https://bugs.openjdk.java.net/browse/JDK-8281660 will be filled in 
>> once the API is further along.
>
> Joe Darcy 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 32 additional commits since 
> the last revision:
> 
>  - Target JDK 20 rather than 19.
>  - Merge branch 'master' into JDK-8266670
>  - Add mask values to constants' javadoc.
>  - Implement review feedback from mlchung.
>  - Fix type in @throws tag.
>  - Merge branch 'master' into JDK-8266670
>  - Respond to review feedback.
>  - Merge branch 'master' into JDK-8266670
>  - Make workding changes suggested in review feedback.
>  - Merge branch 'master' into JDK-8266670
>  - ... and 22 more: 
> https://git.openjdk.java.net/jdk/compare/1545e825...05cf2d8b

src/java.base/share/classes/java/lang/module/ModuleDescriptor.java line 130:

> 128: MANDATED(AccessFlag.MANDATED.mask());
> 129: 
> 130: private int mask;

it should be declared final ?

src/java.base/share/classes/java/lang/module/ModuleDescriptor.java line 134:

> 132: this.mask = mask;
> 133: }
> 134: private int mask() {return mask;}

seem useless, `mask` can be accessed directly

-

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


Re: RFR: 8262889: Compiler implementation for Record Patterns [v7]

2022-05-25 Thread Rémi Forax
On Wed, 25 May 2022 04:20:35 GMT, Jan Lahoda  wrote:

>> 8262889: Compiler implementation for Record Patterns
>> 
>> A first version of a patch that introduces record patterns into javac as a 
>> preview feature. For the specification, please see:
>> http://cr.openjdk.java.net/~gbierman/jep427+405/jep427+405-20220426/specs/patterns-switch-record-patterns-jls.html
>> 
>> There are two notable tricky parts:
>> -in the parser, it was necessary to improve the `analyzePattern` method to 
>> handle nested/record patterns, while still keeping error recovery reasonable
>> -in the `TransPatterns`, the desugaring of the record patterns is very 
>> straightforward - effectivelly the record patterns are desugared into 
>> guards/conditions. This will likely be improved in some future 
>> version/preview
>> 
>> `MatchException` has been extended to cover additional cases related to 
>> record patterns.
>
> Jan Lahoda 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 patterns-record-deconstruction3
>  - Post merge fix.
>  - Merge branch 'master' into patterns-record-deconstruction3
>  - Fixing (non-)exhaustiveness for enum.
>  - Merge branch 'type-pattern-third' into patterns-record-deconstruction3
>  - Merge branch 'master' into type-patterns-third
>  - Using Type.isRaw instead of checking the AST structure.
>  - Exhaustiveness should accept supertypes of the specified type.
>  - Renaming the features from deconstruction pattern to record pattern.
>  - Fixing guards after record patterns.
>  - ... and 24 more: 
> https://git.openjdk.java.net/jdk/compare/742644e2...f49d3f0a

Yai ! champagne (at least virtual).

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v5]

2022-05-18 Thread Rémi Forax
On Wed, 18 May 2022 11:27:24 GMT, Jorn Vernee  wrote:

>> Hi,
>> 
>> This PR brings over commits from the panama-foreign repo. These commits 
>> mostly pertain to the switch to ASM and away from MethodHandle combinators 
>> for the binding recipe specialization. But, there is one more commit which 
>> adds freeing of downcall stubs, since those changes were mostly Java as well.
>> 
>> Thanks,
>> Jorn
>> 
>> Testing: `run-test-jdk_foreign` with `-Dgenerator.sample.factor=-1` on 
>> Windows and Linux.
>
> Jorn Vernee has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains 118 commits:
> 
>  - Merge branch 'JEP-19-ASM' of https://github.com/JornVernee/jdk into 
> JEP-19-ASM
>  - Merge branch 'pr/7959' into JEP-19-ASM
>  - Merge branch 'master' into JEP-19-VM-IMPL2
>  - ifdef NOT_PRODUCT -> ifndef PRODUCT
>  - Missing ASSERT -> NOT_PRODUCT
>  - Cleanup UL usage
>  - Fix failure with SPEC disabled (accidentally dropped change)
>  - indentation
>  - fix space
>  - Merge branch 'master' into JEP-19-ASM
>  - ... and 108 more: 
> https://git.openjdk.java.net/jdk/compare/81e4bdbe...ce5c677a

LGTM !

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v3]

2022-05-17 Thread Rémi Forax
On Tue, 17 May 2022 11:57:01 GMT, Jorn Vernee  wrote:

>> src/java.base/share/classes/jdk/internal/foreign/abi/SoftReferenceCache.java 
>> line 42:
>> 
>>> 40: 
>>> 41: private class Node {
>>> 42: private SoftReference ref;
>> 
>> this code looks like a double check locking so ref should be volatile
>
> Thanks. I thought the `moniterenter` & `monitorexit` were enough here for 
> visibility. I've read up on this and it looks like `volatile` is needed to 
> correctly order the constructor and apply call (and contents) before the 
> write to the `ref` field.

yes, otherwise another thread than the one inside the 
`monitorenter`/`monitorexit` that is initializing the object can see the object 
half initialized.

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v3]

2022-05-17 Thread Rémi Forax
On Tue, 17 May 2022 08:16:32 GMT, Maurizio Cimadamore  
wrote:

>> src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java 
>> line 98:
>> 
>>> 96: private static final String CLASS_DATA_DESC = 
>>> methodType(Object.class, MethodHandles.Lookup.class, String.class, 
>>> Class.class).descriptorString();
>>> 97: private static final String RELEASE0_DESC = 
>>> methodType(void.class).descriptorString();
>>> 98: private static final String ACQUIRE0_DESC = 
>>> methodType(void.class).descriptorString();
>> 
>> calling methodType() is quite slow because of the cache of MethodType so 
>> maybe those initialization should be done explicitly in a static block to 
>> avoid to recompute methodType(long).descriptorString() several times
>
> What about using MethodTypeDesc/ClassDesc as building block?

yes, it should be less expensive, the ClassDesc still need to be constructed 
from Class to allow refactoring.

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v3]

2022-05-17 Thread Rémi Forax
On Mon, 16 May 2022 17:40:41 GMT, Jorn Vernee  wrote:

>> Hi,
>> 
>> This PR brings over commits from the panama-foreign repo. These commits 
>> mostly pertain to the switch to ASM and away from MethodHandle combinators 
>> for the binding recipe specialization. But, there is one more commit which 
>> adds freeing of downcall stubs, since those changes were mostly Java as well.
>> 
>> Thanks,
>> Jorn
>> 
>> Testing: `run-test-jdk_foreign` with `-Dgenerator.sample.factor=-1` on 
>> Windows and Linux.
>
> Jorn Vernee has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   BootstrapMethodError -> ExceptionInInitializerError

src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java 
line 943:

> 941: Z, B, S, C, I, J, F, D, L;
> 942: 
> 943: static BasicType of(Class cls) {

This seems a duplication of ASM Type class for no good reason, 
Type.getOpcode(ILOAD) or Type.getOpcode(IRETURN) gives you the proper variant 
opcode

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v3]

2022-05-17 Thread Rémi Forax
On Mon, 16 May 2022 17:40:41 GMT, Jorn Vernee  wrote:

>> Hi,
>> 
>> This PR brings over commits from the panama-foreign repo. These commits 
>> mostly pertain to the switch to ASM and away from MethodHandle combinators 
>> for the binding recipe specialization. But, there is one more commit which 
>> adds freeing of downcall stubs, since those changes were mostly Java as well.
>> 
>> Thanks,
>> Jorn
>> 
>> Testing: `run-test-jdk_foreign` with `-Dgenerator.sample.factor=-1` on 
>> Windows and Linux.
>
> Jorn Vernee has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   BootstrapMethodError -> ExceptionInInitializerError

src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java 
line 967:

> 965: 
> 966: // unaligned constants
> 967: public final static ValueLayout.OfBoolean JAVA_BOOLEAN_UNALIGNED = 
> JAVA_BOOLEAN;

as far as i understand, those constants are accessed from the bytecode, they 
should be in their own class to cleanly separate the specializer part and the 
runtime part.

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v3]

2022-05-17 Thread Rémi Forax
On Mon, 16 May 2022 17:40:41 GMT, Jorn Vernee  wrote:

>> Hi,
>> 
>> This PR brings over commits from the panama-foreign repo. These commits 
>> mostly pertain to the switch to ASM and away from MethodHandle combinators 
>> for the binding recipe specialization. But, there is one more commit which 
>> adds freeing of downcall stubs, since those changes were mostly Java as well.
>> 
>> Thanks,
>> Jorn
>> 
>> Testing: `run-test-jdk_foreign` with `-Dgenerator.sample.factor=-1` on 
>> Windows and Linux.
>
> Jorn Vernee has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   BootstrapMethodError -> ExceptionInInitializerError

src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java 
line 157:

> 155: }
> 156: 
> 157: static MethodHandle doSpecialize(MethodHandle leafHandle, 
> CallingSequence callingSequence, ABIDescriptor abi) {

I think thise method should be split in to, one version for the upcall, one for 
the downcall, i do not see the point of merging the two codes.

src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java 
line 816:

> 814: return;
> 815: }
> 816: if (con instanceof Integer) {

those can use the instanceof + type pattern

-

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


Re: RFR: 8286669: Replace MethodHandle specialization with ASM in mainline [v3]

2022-05-16 Thread Rémi Forax
On Mon, 16 May 2022 17:40:41 GMT, Jorn Vernee  wrote:

>> Hi,
>> 
>> This PR brings over commits from the panama-foreign repo. These commits 
>> mostly pertain to the switch to ASM and away from MethodHandle combinators 
>> for the binding recipe specialization. But, there is one more commit which 
>> adds freeing of downcall stubs, since those changes were mostly Java as well.
>> 
>> Thanks,
>> Jorn
>> 
>> Testing: `run-test-jdk_foreign` with `-Dgenerator.sample.factor=-1` on 
>> Windows and Linux.
>
> Jorn Vernee has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   BootstrapMethodError -> ExceptionInInitializerError

src/java.base/share/classes/jdk/internal/foreign/abi/BindingSpecializer.java 
line 98:

> 96: private static final String CLASS_DATA_DESC = 
> methodType(Object.class, MethodHandles.Lookup.class, String.class, 
> Class.class).descriptorString();
> 97: private static final String RELEASE0_DESC = 
> methodType(void.class).descriptorString();
> 98: private static final String ACQUIRE0_DESC = 
> methodType(void.class).descriptorString();

calling methodType() is quite slow because of the cache of MethodType so maybe 
those initialization should be done explicitly in a static block to avoid to 
recompute methodType(long).descriptorString() several times

src/java.base/share/classes/jdk/internal/foreign/abi/SoftReferenceCache.java 
line 42:

> 40: 
> 41: private class Node {
> 42: private SoftReference ref;

this code looks like a double check locking so ref should be volatile

-

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


Re: RFR: 8277090 : jsr166 refresh for jdk19 [v2]

2022-05-03 Thread Rémi Forax
On Mon, 2 May 2022 23:54:33 GMT, Doug Lea  wrote:

>> src/java.base/share/classes/java/util/concurrent/FutureTask.java line 222:
>> 
>>> 220: throw new IllegalStateException("Task has not 
>>> completed");
>>> 221: }
>>> 222: }
>> 
>> I think the code will be more readable if a switch expression and the arrow 
>> syntax are used
>> 
>> 
>> return switch(state()) {
>> case SUCCESS -> {
>> @SuppressWarnings("unchecked")
>> V result = (V) outcome;
>> yield result;
>> } 
>> case FAILED -> throw new IllegalStateException("Task completed with 
>> exception");
>> ...
>> };
>
> Sorry, I don't understand how it would be more readable. I like new switch 
> features because they extend the range of applicability of switch. But this 
> (and the two others) are just plain vanilla enum-based switches that were 
> handled well, and seem to have the same numbers of lines and structure either 
> way?

It's more readable because it's now clear that the aim is to return the value 
of the switch.
Also a switch expression has to be exhaustive, so there is no need for a 
'default'.

-

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


Re: RFR: 8277090 : jsr166 refresh for jdk19

2022-05-02 Thread Rémi Forax
On Mon, 2 May 2022 10:23:01 GMT, Doug Lea  wrote:

>> src/java.base/share/classes/java/util/concurrent/ExecutorService.java line 
>> 138:
>> 
>>> 136:  * @author Doug Lea
>>> 137:  */
>>> 138: public interface ExecutorService extends Executor, AutoCloseable {
>> 
>> The class documentation should be expanded to explain that an 
>> ExecutorService can be used with a try-with-resources
>
> Most AutoCloseables do not mention this in class-level javadocs. Is there a 
> reason you think this one should?

close() is now equivalent to the method shutdownAndAwaitTermination() shown in 
the javadoc so i believe , replacing it with a try-with-resources is better in 
term of documenting how an executor service can be used

-

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


Re: RFR: 8277090 : jsr166 refresh for jdk19

2022-05-01 Thread Rémi Forax
On Sun, 1 May 2022 10:53:55 GMT, Doug Lea  wrote:

> This is the jsr166 refresh for jdk19. See 
> https://bugs.openjdk.java.net/browse/JDK-8285450 and 
> https://bugs.openjdk.java.net/browse/JDK-8277090

src/java.base/share/classes/java/util/concurrent/ExecutorService.java line 138:

> 136:  * @author Doug Lea
> 137:  */
> 138: public interface ExecutorService extends Executor, AutoCloseable {

The class documentation should be expanded to explain that an ExecutorService 
can be used with a try-with-resources

src/java.base/share/classes/java/util/concurrent/FutureTask.java line 222:

> 220: throw new IllegalStateException("Task has not 
> completed");
> 221: }
> 222: }

I think the code will be more readable if a switch expression and the arrow 
syntax are used


return switch(state()) {
case SUCCESS -> {
@SuppressWarnings("unchecked")
V result = (V) outcome;
yield result;
} 
case FAILED -> throw new IllegalStateException("Task completed with 
exception");
...
};

src/java.base/share/classes/java/util/concurrent/FutureTask.java line 237:

> 235: throw new IllegalStateException("Task has not 
> completed");
> 236: }
> 237: }

Same here !

src/java.base/share/classes/java/util/concurrent/FutureTask.java line 247:

> 245: s = state;
> 246: }
> 247: switch (s) {

same here !

-

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


Re: RFR: 8282508: Updating ASM to 9.2 for JDK 19

2022-03-28 Thread Rémi Forax
On Mon, 28 Mar 2022 16:49:58 GMT, Vicente Romero  wrote:

> Please review this PR which is updating the ASM included in the JDK to ASM 
> 9.2. This version should be included in JDK19. There are basically two 
> commits here, one that was automatically generated and that mostly changes 
> file headers etc and another one, smaller, that make changes to the code to 
> adapt it to our needs, JDK version etc. In this second commit one can see 
> that two classes that were removed by the automatically generated change have 
> been copied back:
> 
> jdk.internal.org.objectweb.asm.commons.RemappingMethodAdapter
> jdk.internal.org.objectweb.asm.commons.RemappingAnnotationAdapter
> 
> This is because package: `jdk.jfr.internal.instrument` needs them.
> 
> TIA

I suppose that you are raising commons.RemappingMethodAdapter and 
commons.RemappingAnnotationAdapter from the dead because you want to fix the 
code in jdk.jfr.internal.instrument later ?

Otherwise it's a little dangerous because that code as started to drift, the 
new remapper has new code not supported by the old remapper. BTW, @deprecated 
on ASM source is equivalent to. @Deprecated + forRemoval in the JDK.

The support of Java 19 is fine, the same code will be included in ASM soon.

-

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


Re: RFR: JDK-8283416: Update java.lang.invoke.MethodHandle to use sealed classes

2022-03-22 Thread Rémi Forax
On Tue, 22 Mar 2022 04:38:15 GMT, ExE Boss  wrote:

> javac should be changed to allow fully qualified access to private inner 
> classes in the permits clause of an enclosing class.

This is not how private works, private means accessible between the '{' and the 
'}' of the class.
The permits clause is declared outside of the '{' and the '}' of the class, 
thus a private member class is not visible from the permits clause.

-

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


Re: RFR: JDK-8282798 java.lang.runtime.Carrier [v10]

2022-03-21 Thread Rémi Forax
On Mon, 21 Mar 2022 05:17:31 GMT, ExE Boss  wrote:

>> Jim Laskey has updated the pull request incrementally with three additional 
>> commits since the last revision:
>> 
>>  - Typos
>>  - Update Carrier.java
>>  - Redo API to use list, bring Carrier.component back
>
> src/java.base/share/classes/java/lang/runtime/Carrier.java line 309:
> 
>> 307: static {
>> 308: LOOKUP = MethodHandles.lookup();
>> 309: UNSAFE = Unsafe.getUnsafe();
> 
> It might be better to use `java.lang.invoke.MethodHandleStatics.UNSAFE`, and 
> probably also `java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP`.

The package is java.lang.runtime not java.lang.invoke so both fields are not 
accessible.

-

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


Re: RFR: 8283237: CallSite should be a sealed class

2022-03-17 Thread Rémi Forax
On Thu, 17 Mar 2022 07:32:40 GMT, liach  wrote:

>> src/java.base/share/classes/java/lang/invoke/CallSite.java line 88:
>> 
>>> 86:  */
>>> 87: public
>>> 88: abstract sealed class CallSite permits ConstantCallSite, 
>>> VolatileCallSite, MutableCallSite {
>> 
>> Nitpicking with my JSR 292 hat,
>> given that the permits clause is reflected in the javadoc,
>> the order should be ConstantCS, MutableCS and VolatileCS,
>> it's both in the lexical order and in the "memory access" of setTarget() 
>> order , from stronger access to weaker access.
>
> I agree that Constant, Mutable, Volatile order is better, ranked by the 
> respective cost for `setTarget()` and (possibly) invocation, and earlier ones 
> in the list are more preferable if conditions allow.
> 
> However, in the current API documentation, the order is Constant, Mutable, 
> and Volatile. Should I update that or leave it?
> 
> /*
>  * 
>  * If a mutable target is not required, an {@code invokedynamic} 
> instruction
>  * may be permanently bound by means of a {@linkplain ConstantCallSite 
> constant call site}.
>  * If a mutable target is required which has volatile variable semantics,
>  * because updates to the target must be immediately and reliably witnessed 
> by other threads,
>  * a {@linkplain VolatileCallSite volatile call site} may be used.
>  * Otherwise, if a mutable target is required,
>  * a {@linkplain MutableCallSite mutable call site} may be used.
>  * 
>  */

For me, this is unrelated, for this paragraph it's easier to explain the 
semantics of MutableCallSite with an otherwise, i.e. it's mutable but you do 
not want the cost of a volatile acces.

-

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


Re: RFR: 8283237: CallSite should be a sealed class

2022-03-17 Thread Rémi Forax
On Wed, 16 Mar 2022 13:09:30 GMT, liach  wrote:

> Change `CallSite` to a sealed class, as `CallSite` is an abstract class which 
> does not allow direct subclassing by users per its documentation. Since I 
> don't have a JBS account, I posted the content for the CSR in a GitHub Gist 
> at https://gist.github.com/150d5aa7f8b13a4deddf95969ad39d73 and wish someone 
> can submit a CSR for me.

src/java.base/share/classes/java/lang/invoke/CallSite.java line 88:

> 86:  */
> 87: public
> 88: abstract sealed class CallSite permits ConstantCallSite, 
> VolatileCallSite, MutableCallSite {

Nitpicking with my JSR 292 hat,
given that the permits clause is reflected in the javadoc,
the order should be ConstantCS, MutableCS and VolatileCS,
it's both in the lexical order and in the "memory access" of setTarget() order 
, from stronger access to weaker access.

-

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


Re: RFR: JDK-8281766: Update java.lang.reflect.Parameter to implement Member

2022-02-15 Thread Rémi Forax
On Tue, 15 Feb 2022 01:13:43 GMT, Joe Darcy  wrote:

> Retrofitting of Parameter to implement Member, an interface already 
> implemented by similar reflective modeling classes.
> 
> Since Parameter is final, there is little compatibility impact from adding a 
> new method.
> 
> Please also review the corresponding CSR:
> 
> https://bugs.openjdk.java.net/browse/JDK-8281767
> 
> I'll update the copyright year before pushing; I judged this as trivial 
> enough to not require a regression test.

I agree with Mandy and David, a Member is the thingy inside a class, so a 
parameter is no a member, it has no declaring class.

-

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


Re: RFR: JDK-8280168: Add Objects.toIdentityString [v7]

2022-01-24 Thread Rémi Forax
On Mon, 24 Jan 2022 21:31:37 GMT, Joe Darcy  wrote:

>> While it is strongly recommend to not use the default toString for a class, 
>> at times it is the least-bad alternative. When that alternative needs to be 
>> used, it would be helpful to have the implementation already available, such 
>> as in Objects.toDefaultString(). This method is analagous to 
>> System.identityHashCode.
>> 
>> Please also review the CSR: https://bugs.openjdk.java.net/browse/JDK-8280184
>
> Joe Darcy 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:
> 
>  - Respond to review feedback.
>  - Merge branch 'master' into JDK-8280168
>  - Merge branch 'master' into JDK-8280168
>  - Appease jcheck.
>  - Add toIdentityString
>  - Respond to review feedback to augment test.
>  - Respond to review feedback.
>  - JDK-8280168 Add Objects.toDefaultString

toIdentityString is a better name than toDefaultString.

It's fine for me but given that "identity" has a slightly different meaning in 
the context of Valhalla that in System.identityHashCode(), it may be good to 
ask Brian about that name.

-

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


Re: RFR: 8261847: performace of java.lang.Record::toString should be improved

2021-11-16 Thread Rémi Forax
On Tue, 16 Nov 2021 13:03:35 GMT, Jim Laskey  wrote:

>> (I'm not reviewer.)
>> 
>> I think `.toArray(Class[]::new)` should be better here. `.toList` seems 
>> unnecessary.
>
> Class[] types = Stream.of(getters)
> .map(g -> g.type().returnType())
> .toArray(Class[]::new);

or do not use a stream but a simple loop, codes in bootstrap methods should be 
low-level

-

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


Re: RFR: 8271820: Implementation of JEP 416: Reimplement Core Reflection with Method Handle [v13]

2021-10-14 Thread Rémi Forax
On Thu, 14 Oct 2021 00:54:57 GMT, Mandy Chung  wrote:

>> src/java.base/share/classes/jdk/internal/reflect/MethodHandleAccessorFactory.java
>>  line 151:
>> 
>>> 149: var setter = isReadOnly ? null : 
>>> JLIA.unreflectField(field, true);
>>> 150: Class type = field.getType();
>>> 151: if (type == Boolean.TYPE) {
>> 
>> dumb question: any reason why `boolean.class` (which is compiled to a LDC) 
>> is not used?
>
> I only see `boolean.class` compiled to `getstatic Boolean.TYPE`.   Is there a 
> javac flag to compile it to a LDC?

The LDC bytecode instruction for a class takes a class name not a descriptor as 
parameter, so there is no way to encode LDC Z. Valhalla may change that.

-

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


Re: RFR: 8274299: Make Method/Constructor/Field accessors @Stable [v4]

2021-10-04 Thread Rémi Forax
On Mon, 4 Oct 2021 15:49:43 GMT, Peter Levart  wrote:

>> This patch improves reflective access speed as shown by the included 
>> benchmarks:
>> 
>> https://jmh.morethan.io/?gists=902f4b43519c4f96c7abcd14cdc2d27d,ac490481e3001c710d75d6071c10b23a
>> 
>> ... and is also a prerequisite to make JEP 416 (Reimplement Core Reflection 
>> with Method Handle) perform better in some circumstances.
>
> Peter Levart has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   More @stable fields in Constructor/Field to align them with Method fields

I miss that, that very cool.

-

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


Re: RFR: 8274299: Make Method/Constructor/Field accessors @Stable [v4]

2021-10-04 Thread Rémi Forax
On Mon, 4 Oct 2021 15:49:43 GMT, Peter Levart  wrote:

>> This patch improves reflective access speed as shown by the included 
>> benchmarks:
>> 
>> https://jmh.morethan.io/?gists=902f4b43519c4f96c7abcd14cdc2d27d,ac490481e3001c710d75d6071c10b23a
>> 
>> ... and is also a prerequisite to make JEP 416 (Reimplement Core Reflection 
>> with Method Handle) perform better in some circumstances.
>
> Peter Levart has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   More @stable fields in Constructor/Field to align them with Method fields

Can you surreptitiously add "java.lang" too (asking for a friend)

-

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


Re: RFR: 8272137: Make Iterable classes streamable

2021-08-14 Thread Rémi Forax
On Mon, 9 Aug 2021 12:28:23 GMT, CC007  
wrote:

> create Streamable and ParallelStreamable interface and use them in Collection 
> and Optional

Hi Rick,
I do not think that such interfaces are a good addition to the JDK,
we do not want to promote the fact that you can create a Stream from an 
Iterable because the resulting Stream is not efficient (or is not as efficient 
as it could be) and we can already uses a Supplier if we want to to 
represent a factory of streams

See my comment on the bug for more details

-

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


Re: RFR: 8270321: Startup regressions in 18-b5 caused by JDK-8266310

2021-07-26 Thread Rémi Forax
On Fri, 23 Jul 2021 18:03:31 GMT, Sergey Chernyshev 
 wrote:

> Dear colleagues,
> 
> Please review the patch that replaces the lambdas with anonymous classes 
> which solves the startup time regression as shown below.
> 
> I attached the Bytestacks flamegraphs for both original (regression) and 
> fixed versions. The flamegraphs clearly show the lambdas were causing the 
> performance issue.
> 
> [bytestacks_flamegraphs.zip](https://github.com/openjdk/jdk/files/6870446/bytestacks_flamegraphs.zip)
> 
> Although the proposed JDK-8270321 patch fixes the startup time (it might 
> appear even better than it was before the regression was introduced, i.e. 
> before JDK-8266310) and generally fixes the footprint regression, it may 
> increase MaxRSS slightly compared to the version before JDK-8266310, which is 
> shown in the below graphs. (updated)
> 
> ![StartupTime2](https://user-images.githubusercontent.com/6394632/126898224-a05fda62-f723-4f2c-9af9-e02cbfe1c9c8.png)
> 
> ![MaxRSS](https://user-images.githubusercontent.com/6394632/126822404-899ab904-efc1-4377-9e0d-d8cdb5c0e5d0.png)
> 
> (update: added ZGC graphs)
> 
> ![StartupTime_ZGC](https://user-images.githubusercontent.com/6394632/126898242-52c09582-c2a4-4623-aad2-f47055277193.png)
> 
> ![MaxRSS_ZGC](https://user-images.githubusercontent.com/6394632/126898244-31c3eeb5-a768-4a52-8960-960cc4a72d7b.png)
> 
> I additionally include the heap objects histograms to show the change does 
> not increase the total live objects size significantly with only 1000 bytes 
> the total difference, namely 1116128 bytes in 25002 live objects after the 
> proposed fix JDK-8270321 compared to 1115128 bytes in 24990 objects in the 
> version with the original patch reverted (i.e. before JDK-8266310).
> 
> [histograms.zip](https://github.com/openjdk/jdk/files/6870457/histograms.zip)
> 
> The patch was tested w/hotspot/tier1/tier2 test groups.

Hi Sergey,
thanks for the explanation, i don't think there is a need for more data with 
-Xint.

Using anonymous classes instead of lambdas is good for me.

-

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


Re: RFR: 8270321: Startup regressions in 18-b5 caused by JDK-8266310

2021-07-23 Thread Rémi Forax
On Fri, 23 Jul 2021 18:03:31 GMT, Sergey Chernyshev 
 wrote:

> Dear colleagues,
> 
> Please review the patch that replaces the lambdas with anonymous classes 
> which solves the startup time regression as shown below.
> 
> I attached the Bytestacks flamegraphs for both original (regression) and 
> fixed versions. The flamegraphs clearly show the lambdas were causing the 
> performance issue.
> 
> [bytestacks_flamegraphs.zip](https://github.com/openjdk/jdk/files/6870446/bytestacks_flamegraphs.zip)
> 
> Although the proposed JDK-8270321 patch fixes the startup time (it might 
> appear even better than it was before the regression was introduced, i.e. 
> before JDK-8266310), it increases MaxRSS slightly compared to the version 
> before JDK-8266310, which is shown in the below graphs.
> 
> ![StartupTime](https://user-images.githubusercontent.com/6394632/126822380-5b01ce90-b249-4294-9a62-8269440f942d.png)
> 
> ![MaxRSS](https://user-images.githubusercontent.com/6394632/126822404-899ab904-efc1-4377-9e0d-d8cdb5c0e5d0.png)
> 
> I additionally include the heap objects histograms to show the change does 
> not increase the total live objects size significantly with only 1000 bytes 
> the total difference, namely 1116128 bytes in 25002 live objects after the 
> proposed fix JDK-8270321 compared to 1115128 bytes in 24990 objects in the 
> version with the original patch reverted (i.e. before JDK-8266310).
> 
> [histograms.zip](https://github.com/openjdk/jdk/files/6870457/histograms.zip)
> 
> The patch was tested w/hotspot/tier1/tier2 test groups.

I don't understand your analysis, you are testing the startup time with -Xint 
which disable JITs, but there is no mention of -Xint in the bug report.
It's obvious to me that there is a regression with -Xint given that the lambda 
creation is using invokedynamic which is only optimizable by JITs. 

I think you should first try to reproduce the issue with the correct flags and 
then follow the advice from Mandy on how to implement the fix. Using an 
anonymous class may introduce more allocation than using a lambda once the code 
is JITed.

-

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


Re: RFR: 6506405: Math.abs(float) is slow

2021-07-07 Thread Rémi Forax
On Wed, 7 Jul 2021 22:22:45 GMT, Joe Darcy  wrote:

> 
> > Your patch change the semantics, actually
> > `Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE`
> > with your patch
> > `Math.abs(Integer.MIN_VALUE) == Integer.MAX_VALUE`
> 
> Does it? The overriding of int arguments shouldn't be affected.

You are right, it does not change abs(int) so it should be Ok.

> 
> -Joe

-

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


Re: RFR: 6506405: Math.abs(float) is slow

2021-07-07 Thread Rémi Forax
On Wed, 7 Jul 2021 20:28:37 GMT, Brian Burkhalter  wrote:

> Please consider this change to make the `float` and `double` versions of 
> `java.lang.Math.abs()` branch-free.

Your patch change the semantics, actually
  `Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE`
with your patch
  `Math.abs(Integer.MIN_VALUE) == Integer.MAX_VALUE`

-

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


Re: [jdk17] RFR: 8268766: Desugaring of pattern matching enum switch should be improved [v2]

2021-06-18 Thread Rémi Forax
On Fri, 18 Jun 2021 09:08:04 GMT, Jan Lahoda  wrote:

>> src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 222:
>> 
>>> 220:   String invocationName,
>>> 221:   MethodType invocationType,
>>> 222:   Object... labels) throws 
>>> Throwable {
>> 
>> Is it not better to take a Class and a String... as separated parameters 
>> instead of taking Object... and doing the conversion to a Class and an array 
>> of String later in Java
>
> This is to represent cases like:
> 
>  E sel = null;
>  switch (sel) {
>  case A -> {}
>  case E e && "B".equals(e.name()) -> {}
>  case C -> {}
>  case E e -> {}
>  }
> 
> 
> The method needs to know which cases represent constants and which represent 
> patterns (even though the primary type of all the patterns will be the enum 
> type), so we cannot easily put the `Class` first (or elide it), and then a 
> `String...`, unless we represent the patterns in the `String...` array 
> somehow.

Ok got it,
At some point, we will have to represent patterns either as String and parse 
them or as Condy of condy if we want a more structured recursive way.

-

PR: https://git.openjdk.java.net/jdk17/pull/81


Re: [jdk17] RFR: 8268766: Desugaring of pattern matching enum switch should be improved [v2]

2021-06-17 Thread Rémi Forax
On Thu, 17 Jun 2021 18:33:56 GMT, Jan Lahoda  wrote:

>> Currently, an enum switch with patterns is desugared in a very non-standard, 
>> and potentially slow, way. It would be better to use the standard 
>> `typeSwitch` bootstrap to classify the enum constants. The bootstrap needs 
>> to accept enum constants as labels in order to allow this. A complication is 
>> that if an enum constant is missing, that is not an incompatible change for 
>> the switch, and the switch should simply work as if the case for the missing 
>> constant didn't exist. So, the proposed solution is to have a new bootstrap 
>> `enumConstant` that converts the enum constant name to the enum constant, 
>> returning `null`, if the constant does not exist. It delegates to 
>> `ConstantBootstraps.enumConstant` to do the actual conversion. And 
>> `typeSwitch` accepts `null`s as padding.
>> 
>> How does this look?
>
> Jan Lahoda has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Creating a new bootstrap method for (pattern matching) enum switches, as 
> suggested.

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 222:

> 220:   String invocationName,
> 221:   MethodType invocationType,
> 222:   Object... labels) throws Throwable 
> {

Is it not better to take a Class and a String... as separated parameters 
instead of taking Object... and doing the conversion to a Class and an array of 
String later in Java

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 238:

> 236: MethodHandle target =
> 237: MethodHandles.insertArguments(DO_ENUM_SWITCH, 2, 
> (Object) labels);
> 238: target = MethodHandles.explicitCastArguments(target, 
> invocationType);

why explicitCast is used here instead of the classical cast asType() ?

-

PR: https://git.openjdk.java.net/jdk17/pull/81


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v13]

2021-06-05 Thread Rémi Forax
On Fri, 4 Jun 2021 20:20:26 GMT, Jan Lahoda  wrote:

>> This is a preview of a patch implementing JEP 406: Pattern Matching for 
>> switch (Preview):
>> https://bugs.openjdk.java.net/browse/JDK-8213076
>> 
>> The current draft of the specification is here:
>> http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210430/specs/patterns-switch-jls.html
>> 
>> A summary of notable parts of the patch:
>> -to support cases expressions and patterns in cases, there is a new common 
>> superinterface for expressions and patterns, `CaseLabelTree`, which 
>> expressions and patterns implement, and a list of case labels is returned 
>> from `CaseTree.getLabels()`.
>> -to support `case default`, there is an implementation of `CaseLabelTree` 
>> that represents it (`DefaultCaseLabelTree`). It is used also to represent 
>> the conventional `default` internally and in the newly added methods.
>> -in the parser, parenthesized patterns and expressions need to be 
>> disambiguated when parsing case labels.
>> -Lower has been enhanced to handle `case null` for ordinary 
>> (boxed-primitive, String, enum) switches. This is a bit tricky for boxed 
>> primitives, as there is no value that is not part of the input domain so 
>> that could be used to represent `case null`. Requires a bit shuffling with 
>> values.
>> -TransPatterns has been enhanced to handle the pattern matching switch. It 
>> produces code that delegates to a new bootstrap method, that will classify 
>> the input value to the switch and return the case number, to which the 
>> switch then jumps. To support guards, the switches (and the bootstrap 
>> method) are restartable. The bootstrap method as such is written very simply 
>> so far, but could be much more optimized later.
>> -nullable type patterns are `case String s, null`/`case null, String 
>> s`/`case null: case String s:`/`case String s: case null:`, handling of 
>> these required a few tricks in `Attr`, `Flow` and `TransPatterns`.
>> 
>> The specdiff for the change is here (to be updated):
>> http://cr.openjdk.java.net/~jlahoda/8265981/specdiff.preview.01/overview-summary.html
>
> Jan Lahoda has updated the pull request incrementally with two additional 
> commits since the last revision:
> 
>  - Applying review feedback.
>  - Tweaking javadoc.

Dynamic constants are needed when de-structuring classes that are not record at 
top-level, to make the type that will carry the bindings, from invokedynamic to 
where they are accessed, opaque. So dynamic constants are not needed yet !

-

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


Re: RFR: 8268124: Update java.lang to use switch expressions [v3]

2021-06-03 Thread Rémi Forax
On Thu, 3 Jun 2021 11:01:02 GMT, Patrick Concannon  
wrote:

>> Hi,
>> 
>> Could someone please review my code for updating the code in the `java.lang` 
>> packages to make use of the switch expressions?
>> 
>> Kind regards,
>> Patrick
>
> Patrick Concannon has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   8268124: small refactoring; fixed misplaced comment and added missing 
> lambda operator

Looks good to me

-

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


Re: RFR: 8268124: Update java.lang to use switch expressions [v3]

2021-06-03 Thread Rémi Forax
On Thu, 3 Jun 2021 10:57:16 GMT, Patrick Concannon  
wrote:

> My mistake. I've replaced the colon now with the lambda operator.

Drive by comment, in term of name, `->` is the arrow operator not the lambda 
operator.
- lambda = parameters + arrow + code
- arrow case =  case + arrow + code

The difference is important because a lambda is a function while an arrow case 
is a block.

-

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


Re: RFR: 8199318: add idempotent copy operation for Map.Entry

2021-06-02 Thread Rémi Forax
On Wed, 2 Jun 2021 17:12:21 GMT, Stuart Marks  wrote:

> A quick search reveals that Guava has a public subclass of 
> SimpleImmutableEntry:
> https://guava.dev/releases/30.1.1-jre/api/docs/com/google/common/cache/RemovalNotification.html

>There are possibly others. It doesn't seem worth the incompatibility to me, as 
>it would break stuff in order to have only a "cleaner" meaning for 
>"immutable." Also, there are other classes in the JDK that claim they are 
>immutable but which can be subclassed, e.g., BigInteger. I don't see a good 
>way of fixing this.

Thanks, i've done some digging too,
I foolishly hoped that nobody would subclass a class with `Immutable` in its 
name,
oh boy i was wrong :)

So documenting the existing behavior seems the only possible way.

-

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


Re: RFR: 8268124: Update java.lang to use switch expressions

2021-06-02 Thread Rémi Forax
On Wed, 2 Jun 2021 15:25:16 GMT, Patrick Concannon  
wrote:

> Hi,
> 
> Could someone please review my code for updating the code in the `java.lang` 
> packages to make use of the switch expressions?
> 
> Kind regards,
> Patrick

src/java.base/share/classes/java/lang/runtime/ObjectMethods.java line 366:

> 364: }
> 365: default -> throw new IllegalArgumentException(methodName);
> 366: };

I thinki it's simpler to have something like that

  var handle = switch(methodName) {
...
  };
  return methodType != null ? new ConstantCallSite(handle) : handle;

-

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


Re: RFR: 8268124: Update java.lang to use switch expressions

2021-06-02 Thread Rémi Forax
On Wed, 2 Jun 2021 15:25:16 GMT, Patrick Concannon  
wrote:

> Hi,
> 
> Could someone please review my code for updating the code in the `java.lang` 
> packages to make use of the switch expressions?
> 
> Kind regards,
> Patrick

src/java.base/share/classes/java/lang/invoke/MethodHandleProxies.java line 278:

> 276: private static boolean isObjectMethod(Method m) {
> 277: return switch (m.getName()) {
> 278: case "toString" -> (m.getReturnType() == String.class

the extra parenthesis are not needed

-

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


Re: RFR: 8268124: Update java.lang to use switch expressions

2021-06-02 Thread Rémi Forax
On Wed, 2 Jun 2021 15:25:16 GMT, Patrick Concannon  
wrote:

> Hi,
> 
> Could someone please review my code for updating the code in the `java.lang` 
> packages to make use of the switch expressions?
> 
> Kind regards,
> Patrick

src/java.base/share/classes/java/lang/invoke/MemberName.java line 331:

> 329: assert(false) : this+" != 
> "+MethodHandleNatives.refKindName((byte)originalRefKind);
> 330: yield true;
> 331: }

this code always yield true, better to check if the assert are enabled, do the 
switch in that case and always return true

-

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


Re: RFR: 8268124: Update java.lang to use switch expressions

2021-06-02 Thread Rémi Forax
On Wed, 2 Jun 2021 15:25:16 GMT, Patrick Concannon  
wrote:

> Hi,
> 
> Could someone please review my code for updating the code in the `java.lang` 
> packages to make use of the switch expressions?
> 
> Kind regards,
> Patrick

src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java line 
1663:

> 1661: case D_TYPE -> mv.visitInsn(Opcodes.DCONST_0);
> 1662: case L_TYPE -> mv.visitInsn(Opcodes.ACONST_NULL);
> 1663: default -> throw new InternalError("unknown type: " + type);

perhaps

  mv.visitInsn(switch(type) { ...

-

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


Re: RFR: 8199318: add idempotent copy operation for Map.Entry

2021-06-02 Thread Rémi Forax
On Wed, 2 Jun 2021 00:39:25 GMT, Stuart Marks  wrote:

> I'm fixing this along with a couple intertwined issues.
> 
> 1. Add Map.Entry::copyOf as an idempotent copy operation.
> 
> 2. Clarify that AbstractMap.SimpleImmutableEntry is itself unmodifiable (not 
> really immutable) but that subclasses can be modifiable.
> 
> 3. Clarify some confusing, historical wording about Map.Entry instances being 
> obtainable only via iteration of a Map's entry-set view. This was never 
> really true, since anyone could implement the Map.Entry interface, and it 
> certainly was not true since JDK 1.6 when SimpleEntry and 
> SimpleImmutableEntry were added.

LGTM,
i wonder if we should not declare SimpleImmutableEntry final, while it's not a 
backward compatible change,
it's may be better on the long term because SimpleImmutableEntry is already 
used as an immutable type,
so instead of documenting the fact that SimpleImmutableEntry is not declared 
final thus SimpleImmutableEntry as a type does not guarantte shallow 
immutability, it may be better to fix the root cause.

-

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


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v5]

2021-05-27 Thread Rémi Forax
On Wed, 26 May 2021 17:52:36 GMT, Jan Lahoda  wrote:

>> This is a preview of a patch implementing JEP 406: Pattern Matching for 
>> switch (Preview):
>> https://bugs.openjdk.java.net/browse/JDK-8213076
>> 
>> The current draft of the specification is here:
>> http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210430/specs/patterns-switch-jls.html
>> 
>> A summary of notable parts of the patch:
>> -to support cases expressions and patterns in cases, there is a new common 
>> superinterface for expressions and patterns, `CaseLabelTree`, which 
>> expressions and patterns implement, and a list of case labels is returned 
>> from `CaseTree.getLabels()`.
>> -to support `case default`, there is an implementation of `CaseLabelTree` 
>> that represents it (`DefaultCaseLabelTree`). It is used also to represent 
>> the conventional `default` internally and in the newly added methods.
>> -in the parser, parenthesized patterns and expressions need to be 
>> disambiguated when parsing case labels.
>> -Lower has been enhanced to handle `case null` for ordinary 
>> (boxed-primitive, String, enum) switches. This is a bit tricky for boxed 
>> primitives, as there is no value that is not part of the input domain so 
>> that could be used to represent `case null`. Requires a bit shuffling with 
>> values.
>> -TransPatterns has been enhanced to handle the pattern matching switch. It 
>> produces code that delegates to a new bootstrap method, that will classify 
>> the input value to the switch and return the case number, to which the 
>> switch then jumps. To support guards, the switches (and the bootstrap 
>> method) are restartable. The bootstrap method as such is written very simply 
>> so far, but could be much more optimized later.
>> -nullable type patterns are `case String s, null`/`case null, String 
>> s`/`case null: case String s:`/`case String s: case null:`, handling of 
>> these required a few tricks in `Attr`, `Flow` and `TransPatterns`.
>> 
>> The specdiff for the change is here (to be updated):
>> http://cr.openjdk.java.net/~jlahoda/8265981/specdiff.preview.01/overview-summary.html
>
> Jan Lahoda has updated the pull request with a new target base due to a merge 
> or a rebase. The pull request now contains 12 commits:
> 
>  - Post-merge fix - need to include jdk.internal.javac in the list of 
> packages used by jdk.compiler again, as we now (again) have a preview feature 
> in javac.
>  - Correcting LineNumberTable for rule switches.
>  - Merging master into JDK-8262891
>  - Fixing various error-related bugs.
>  - Avoiding fall-through from the total case to a synthetic default but 
> changing total patterns to default.
>  - Reflecting recent spec changes.
>  - Reflecting review comments.
>  - Reflecting review comments on SwitchBootstraps.
>  - Trailing whitespaces.
>  - Cleanup, reflecting review comments.
>  - ... and 2 more: 
> https://git.openjdk.java.net/jdk/compare/083416d3...fd748501

> > I've updated the code to produce better/more useful LineNumberTable for 
> > rule switches.
> 
> @lahodaj I re-tested previous example and tested few others. Now everything 
> seems to be good with `LineNumberTable` entries +1
> 
[...]
> Don't know about importance of this, and whether this was expected, but 
> decided to mention.

Look likes a mistake for me, you only need a StackFrame in front of the call to 
invokedynamic if it's the target of a goto and in your example, there is no 
guard so no backward goto.

-

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


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v4]

2021-05-26 Thread Rémi Forax
On Tue, 25 May 2021 16:14:56 GMT, Jan Lahoda  wrote:

> I'd like to note this is a preview feature - we can change the desugaring. At 
> the same time, I don't think this does not work with sub-patterns (those can 
> be easily desugared to guards, I think).

Yes, but in that case the classcheck du to a sub-pattern matching will be 
either an instanceof or some other invokedynamic.
Having several indy will bloat the code and if we use instanceof, why not using 
instanceof all along the way.

> Regarding efficiency, it may be a balance between classfile overhead (which 
> will be higher if we need to desugar every guard to a separate method), and 
> the possibility to tweak the matching at runtime.

I fear more the 2 bytes length bytecode limit of a method than the constant 
pool length limit mostly because people are already using a bunch of lambdas to 
simulate pattern matching.

-

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


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v4]

2021-05-25 Thread Rémi Forax
On Tue, 25 May 2021 14:22:57 GMT, Jan Lahoda  wrote:

> The reason for this integer (which is not a constant in the case of this 
> switch) is to restart the matching in case guards fail to "match". 
> Considering the example here:
> 
> ```
> class Example {
> void example(Object o) {
> switch (o) {
> case String s && s.length() == 0 ->
> System.out.println("1st case");
> case String s && s.length() == 1 ->  // line 6
> System.out.println("2nd case");  // line 7
> case String s -> // line 8
> System.out.println("3rd case");  // line 9
> default ->   // line 10
> System.out.println("default case");  // line 11
> }
> }
> }
> ```
> 
> If `o` is `String`, then the first call to indy will be `indy[...](o, 0)`, 
> returning `0`. Then the guard will be evaluated `s.length() == 0`. If the 
> length is not zero, the local variable 3 will be reassigned to `1`(bytecode 
> index 58, 59) and the whole switch is restarted - just this time, the 
> matching in the indy will start at index `1`, not `0`, i.e. `indy[...](o, 
> 1)`. And so on. I believe there is a text explaining the meaning of the 
> parameter in the javadoc of the bootstrap, and in TransPatterns in javac.

The problem with this design is that calling example("foo") forces the VM will 
do 6 checkcast String on "foo", and it doesn't work with sub-patterns. 
Desugaring the guards as static method like with lambdas seems more promising, 
indy can be called with the pairs [String, MethodHandle(s -> s.length() == 0)], 
[String, MethodHandle(s -> s.length() == 0)] and [_,_]  (with the guards passed 
as a constant method handles again like lambdas are desugared).
It means that the indy needs to capture all local variables that are used in 
the guards, instead of passing an int.

I believe that a translation using constant method handles for guards is far 
more efficient than using an int and a backward branch but it has a higher cost 
in term of runtime data structures.

-

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


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v4]

2021-05-25 Thread Rémi Forax
On Tue, 25 May 2021 12:20:02 GMT, Jan Lahoda  wrote:

> Thanks Evgeny, I'll take a look.
> 
> @forax, do you mean why there is "0" in:
> 11: invokedynamic #13, 0
> ?

Not this one, the one on the stack.

7: iconst_0   < this zero
8: istore_3
9: aload_2
10: iload_3
11: invokedynamic #13, 0 // InvokeDynamic
#0:typeSwitch:(Ljava/lang/Object;I)I

Why the descriptor is (Ljava/lang/Object;I)I instead of (Ljava/lang/Object;)I,
what is the semantics associated to that integer ?

> The "0" is an artifact of how invokedynamic is represented in the classfile 
> (invokedynamic, 2 bytes of constant pool reference, byte 0, byte 0) - javap 
> shows the value of the first zero byte. That is probably not needed anymore, 
> but there is nothing special in this patch, I think - all invokedynamic calls 
> look like this, AFAIK.

I know that a little to well, i'm one of the guys behind the design of indy :)

-

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


Re: RFR: 8191441: (Process) add Readers and Writer access to java.lang.Process streams

2021-05-21 Thread Rémi Forax
On Thu, 20 May 2021 20:37:57 GMT, Roger Riggs  wrote:

> OutputStreamWriter would be a better choice with that in mind. It does not 
> have the convenience methods for converting various types to strings but 
> would not hide the exceptions. Developers could wrap it in a PrintWriter to 
> get the convenience and take on the responsibility of dealing with exceptions 
> by polling.

yes, instead of OutputStreamWriter, i wonder if BufferedWriter is not better 
given that reader part uses BufferedReader and that is mirror 
java.nio.file.Files which also uses BufferedReader/BufferedWriter as types for 
the pair reader/writer.

-

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


Re: RFR: 8191441: (Process) add Readers and Writer access to java.lang.Process streams

2021-05-20 Thread Rémi Forax
On Thu, 20 May 2021 19:57:22 GMT, Roger Riggs  wrote:

> Methods are added to java.lang.Process to read and write characters and lines 
> from and to a spawned Process.
> The Charset used to encode and decode characters to bytes can be specified or 
> use the
> operating system native encoding as is available from the "native.encoding" 
> system property.

I've added the same comment on the bug itself.
I don't think that using PrintWriter is a good idea here given that a 
PrintWriter shallow the IOException

-

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


Re: RFR: 8266846: Add java.time.InstantSource [v3]

2021-05-19 Thread Rémi Forax
On Tue, 18 May 2021 23:18:42 GMT, Stephen Colebourne  
wrote:

>> 8266846: Add java.time.InstantSource
>
> Stephen Colebourne has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   8266846: Add java.time.InstantSource

my bad

-

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


Re: RFR: 8266846: Add java.time.InstantSource [v3]

2021-05-19 Thread Rémi Forax
On Tue, 18 May 2021 23:18:42 GMT, Stephen Colebourne  
wrote:

>> 8266846: Add java.time.InstantSource
>
> Stephen Colebourne has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   8266846: Add java.time.InstantSource

It's a side effect of JEP 403, i believe

-

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


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview) [v2]

2021-05-17 Thread Rémi Forax
On Mon, 17 May 2021 19:04:11 GMT, Jan Lahoda  wrote:

>> This is a preview of a patch implementing JEP 406: Pattern Matching for 
>> switch (Preview):
>> https://bugs.openjdk.java.net/browse/JDK-8213076
>> 
>> The current draft of the specification is here:
>> http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210430/specs/patterns-switch-jls.html
>> 
>> A summary of notable parts of the patch:
>> -to support cases expressions and patterns in cases, there is a new common 
>> superinterface for expressions and patterns, `CaseLabelTree`, which 
>> expressions and patterns implement, and a list of case labels is returned 
>> from `CaseTree.getLabels()`.
>> -to support `case default`, there is an implementation of `CaseLabelTree` 
>> that represents it (`DefaultCaseLabelTree`). It is used also to represent 
>> the conventional `default` internally and in the newly added methods.
>> -in the parser, parenthesized patterns and expressions need to be 
>> disambiguated when parsing case labels.
>> -Lower has been enhanced to handle `case null` for ordinary 
>> (boxed-primitive, String, enum) switches. This is a bit tricky for boxed 
>> primitives, as there is no value that is not part of the input domain so 
>> that could be used to represent `case null`. Requires a bit shuffling with 
>> values.
>> -TransPatterns has been enhanced to handle the pattern matching switch. It 
>> produces code that delegates to a new bootstrap method, that will classify 
>> the input value to the switch and return the case number, to which the 
>> switch then jumps. To support guards, the switches (and the bootstrap 
>> method) are restartable. The bootstrap method as such is written very simply 
>> so far, but could be much more optimized later.
>> -nullable type patterns are `case String s, null`/`case null, String 
>> s`/`case null: case String s:`/`case String s: case null:`, handling of 
>> these required a few tricks in `Attr`, `Flow` and `TransPatterns`.
>> 
>> The specdiff for the change is here (to be updated):
>> http://cr.openjdk.java.net/~jlahoda/8265981/specdiff.preview.01/overview-summary.html
>
> Jan Lahoda has updated the pull request incrementally with three additional 
> commits since the last revision:
> 
>  - Reflecting recent spec changes.
>  - Reflecting review comments.
>  - Reflecting review comments on SwitchBootstraps.

It's not clear to me if it's the first change and several will follow or not.

The code looks good but the metaprotocol is not the right one IMO,
i would prefer the one we discuss in April
https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-April/002992.html

But this can be tackle in another PR

-

Marked as reviewed by fo...@github.com (no known OpenJDK username).

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


Re: RFR: 8266846: Add java.time.InstantSource

2021-05-17 Thread Rémi Forax
On Mon, 17 May 2021 07:31:45 GMT, Stephen Colebourne  
wrote:

>> src/java.base/share/classes/java/time/InstantSource.java line 93:
>> 
>>> 91:  * @since 17
>>> 92:  */
>>> 93: public interface InstantSource {
>> 
>> Should not we add `@FunctionalInterface`? I can easily imagine this 
>> interface being used in tests where we can define the `InstantSource` with 
>> lambdas.
>
> `@FunctionalInterface` isn't required for use by lambdas. I wasn't initially 
> convinced using it here was the right choice.

Right, it's about signaling that it's safe to be used with a 
lambda/method-reference, so it's not required but a nice to have, very like 
@Override.

-

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


Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview)

2021-05-13 Thread Rémi Forax
On Tue, 4 May 2021 16:41:44 GMT, Jan Lahoda  wrote:

> This is a preview of a patch implementing JEP 406: Pattern Matching for 
> switch (Preview):
> https://bugs.openjdk.java.net/browse/JDK-8213076
> 
> The current draft of the specification is here:
> http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210430/specs/patterns-switch-jls.html
> 
> A summary of notable parts of the patch:
> -to support cases expressions and patterns in cases, there is a new common 
> superinterface for expressions and patterns, `CaseLabelTree`, which 
> expressions and patterns implement, and a list of case labels is returned 
> from `CaseTree.getLabels()`.
> -to support `case default`, there is an implementation of `CaseLabelTree` 
> that represents it (`DefaultCaseLabelTree`). It is used also to represent the 
> conventional `default` internally and in the newly added methods.
> -in the parser, parenthesized patterns and expressions need to be 
> disambiguated when parsing case labels.
> -Lower has been enhanced to handle `case null` for ordinary (boxed-primitive, 
> String, enum) switches. This is a bit tricky for boxed primitives, as there 
> is no value that is not part of the input domain so that could be used to 
> represent `case null`. Requires a bit shuffling with values.
> -TransPatterns has been enhanced to handle the pattern matching switch. It 
> produces code that delegates to a new bootstrap method, that will classify 
> the input value to the switch and return the case number, to which the switch 
> then jumps. To support guards, the switches (and the bootstrap method) are 
> restartable. The bootstrap method as such is written very simply so far, but 
> could be much more optimized later.
> -nullable type patterns are `case String s, null`/`case null, String s`/`case 
> null: case String s:`/`case String s: case null:`, handling of these required 
> a few tricks in `Attr`, `Flow` and `TransPatterns`.
> 
> The specdiff for the change is here (to be updated):
> http://cr.openjdk.java.net/~jlahoda/8265981/specdiff.preview.01/overview-summary.html

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 127:

> 125: Stream.of(labels).forEach(SwitchBootstraps::verifyLabel);
> 126: 
> 127: return new TypeSwitchCallSite(invocationType, labels);

See why below

  MethodHandle target = MethodHandles.insertArguments(DO_SWITCH, 2, labels);
  return new ConstantCallsite(target);

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 134:

> 132: throw new IllegalArgumentException("null label found");
> 133: }
> 134: if (label.getClass() != Class.class &&

store `label.getClass` in a local variable,
it's too bad that you can no use pattern matching here :)

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 141:

> 139: }
> 140: 
> 141: static class TypeSwitchCallSite extends ConstantCallSite {

That's weird, having a callsite extending MutableCallSite is expected but 
having a callsite extending constant callsite is useless because you can not 
change it after being constructed.

As an interesting trivia, the VM does not store the CallSite returned by the 
BSM, but only the target inside it.
So there is no point of keeping a ConstantCallSite around.  

So `doSwitch()` should be static and takes the array of Object[] as parameter, 
will array will be injected with an insertArguments().

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 157:

> 155: Class targetClass = target.getClass();
> 156: for (int i = startIndex; i < labels.length; i++) {
> 157: if (labels[i] instanceof Class) {

label[i] should be stored is a local variable and
using `instanceof Class c` (like the other instanceof below) will make the 
code more readable

-

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


Re: RFR: 8263087: Add a MethodHandle combinator that switches over a set of MethodHandles

2021-05-12 Thread Rémi Forax
On Thu, 8 Apr 2021 18:51:21 GMT, Jorn Vernee  wrote:

> This patch adds a `tableSwitch` combinator that can be used to switch over a 
> set of method handles given an index, with a fallback in case the index is 
> out of bounds, much like the `tableswitch` bytecode. Here is a description of 
> how it works (copied from the javadoc):
> 
>  Creates a table switch method handle, which can be used to switch over a 
> set of target
>  method handles, based on a given target index, called selector.
> 
>  For a selector value of {@code n}, where {@code n} falls in the range 
> {@code [0, N)},
>  and where {@code N} is the number of target method handles, the table 
> switch method
>  handle will invoke the n-th target method handle from the list of target 
> method handles.
> 
>  For a selector value that does not fall in the range {@code [0, N)}, the 
> table switch
>  method handle will invoke the given fallback method handle.
> 
>  All method handles passed to this method must have the same type, with 
> the additional
>  requirement that the leading parameter be of type {@code int}. The 
> leading parameter
>  represents the selector.
> 
>  Any trailing parameters present in the type will appear on the returned 
> table switch
>  method handle as well. Any arguments assigned to these parameters will 
> be forwarded,
>  together with the selector value, to the selected method handle when 
> invoking it.
> 
> The combinator does not support specifying the starting index, so the switch 
> cases always run from 0 to however many target handles are specified. A 
> starting index can be added manually with another combination step that 
> filters the input index by adding or subtracting a constant from it, which 
> does not affect performance. One of the reasons for not supporting a starting 
> index is that it allows for more lambda form sharing, but also simplifies the 
> implementation somewhat. I guess an open question is if a convenience 
> overload should be added for that case?
> 
> Lookup switch can also be simulated by filtering the input through an 
> injection function that translates it into a case index, which has also 
> proven to have the ability to have comparable performance to, or even better 
> performance than, a bytecode-native `lookupswitch` instruction. I plan to add 
> such an injection function to the runtime libraries in the future as well. 
> Maybe at that point it could be evaluated if it's worth it to add a lookup 
> switch combinator as well, but I don't see an immediate need to include it in 
> this patch.
> 
> The current bytecode intrinsification generates a call for each switch case, 
> which guarantees full inlining of the target method handles. Alternatively we 
> could only have 1 callsite at the end of the switch, where each case just 
> loads the target method handle, but currently this does not allow for 
> inlining of the handles, since they are not constant.
> 
> Maybe a future C2 optimization could look at the receiver input for 
> invokeBasic call sites, and if the input is a phi node, clone the call for 
> each constant input of the phi. I believe that would allow simplifying the 
> bytecode without giving up on inlining.
> 
> Some numbers from the added benchmarks:
> 
> Benchmark(numCases)  (offset)  
> (sorted)  Mode  Cnt   Score   Error  Units
> MethodHandlesTableSwitchConstant.testSwitch   5 0   
> N/A  avgt   30   4.186 � 0.054  ms/op
> MethodHandlesTableSwitchConstant.testSwitch   5   150   
> N/A  avgt   30   4.164 � 0.057  ms/op
> MethodHandlesTableSwitchConstant.testSwitch  10 0   
> N/A  avgt   30   4.124 � 0.023  ms/op
> MethodHandlesTableSwitchConstant.testSwitch  10   150   
> N/A  avgt   30   4.126 � 0.025  ms/op
> MethodHandlesTableSwitchConstant.testSwitch  25 0   
> N/A  avgt   30   4.137 � 0.042  ms/op
> MethodHandlesTableSwitchConstant.testSwitch  25   150   
> N/A  avgt   30   4.113 � 0.016  ms/op
> MethodHandlesTableSwitchConstant.testSwitch  50 0   
> N/A  avgt   30   4.118 � 0.028  ms/op
> MethodHandlesTableSwitchConstant.testSwitch  50   150   
> N/A  avgt   30   4.127 � 0.019  ms/op
> MethodHandlesTableSwitchConstant.testSwitch 100 0   
> N/A  avgt   30   4.116 � 0.013  ms/op
> MethodHandlesTableSwitchConstant.testSwitch 100   150   
> N/A  avgt   30   4.121 � 0.020  ms/op
> MethodHandlesTableSwitchOpaqueSingle.testSwitch   5 0   
> N/A  avgt   30   4.113 � 0.009  ms/op
> MethodHandlesTableSwitchOpaqueSingle.testSwitch   5   150   
> N/A  avgt   30   4.149 � 0.041  ms/op
> MethodHandlesTableSwitchOpaqueSingle.testSwitch  10 0   
> N/A  avgt   30   4.121 � 0.026  ms/op
> 

Re: RFR: 8262891: Compiler implementation for Pattern Matching for switch (Preview)

2021-05-11 Thread Rémi Forax
On Tue, 4 May 2021 16:41:44 GMT, Jan Lahoda  wrote:

> This is a preview of a patch implementing JEP 406: Pattern Matching for 
> switch (Preview):
> https://bugs.openjdk.java.net/browse/JDK-8213076
> 
> The current draft of the specification is here:
> http://cr.openjdk.java.net/~gbierman/jep406/jep406-20210430/specs/patterns-switch-jls.html
> 
> A summary of notable parts of the patch:
> -to support cases expressions and patterns in cases, there is a new common 
> superinterface for expressions and patterns, `CaseLabelTree`, which 
> expressions and patterns implement, and a list of case labels is returned 
> from `CaseTree.getLabels()`.
> -to support `case default`, there is an implementation of `CaseLabelTree` 
> that represents it (`DefaultCaseLabelTree`). It is used also to represent the 
> conventional `default` internally and in the newly added methods.
> -in the parser, parenthesized patterns and expressions need to be 
> disambiguated when parsing case labels.
> -Lower has been enhanced to handle `case null` for ordinary (boxed-primitive, 
> String, enum) switches. This is a bit tricky for boxed primitives, as there 
> is no value that is not part of the input domain so that could be used to 
> represent `case null`. Requires a bit shuffling with values.
> -TransPatterns has been enhanced to handle the pattern matching switch. It 
> produces code that delegates to a new bootstrap method, that will classify 
> the input value to the switch and return the case number, to which the switch 
> then jumps. To support guards, the switches (and the bootstrap method) are 
> restartable. The bootstrap method as such is written very simply so far, but 
> could be much more optimized later.
> -nullable type patterns are `case String s, null`/`case null, String s`/`case 
> null: case String s:`/`case String s: case null:`, handling of these required 
> a few tricks in `Attr`, `Flow` and `TransPatterns`.
> 
> The specdiff for the change is here (to be updated):
> http://cr.openjdk.java.net/~jlahoda/8265981/specdiff.preview.01/overview-summary.html

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 77:

> 75: }
> 76: 
> 77: private static MethodHandle typeInitHook(T 
> receiver) {

There is no point to have a type parameter here,

  private static MethodHandle typeInitHook(CallSite receiver) {

will work the same

src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java line 131:

> 129: 
> 130: private static void verifyLabel(Object label) {
> 131: if (Objects.isNull(label)) {

`if (label == true) {` is more readable as said in the javadoc of 
`Objects.isNull`

-

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


Re: RFR: 8264777: Overload optimized FileInputStream::readAllBytes [v2]

2021-05-05 Thread Rémi Forax
On Wed, 5 May 2021 06:50:17 GMT, Vladimir Sitnikov  
wrote:

>> Brian Burkhalter has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   8264777: Handle cases where length() returns zero
>
> src/java.base/share/classes/java/io/FileInputStream.java line 284:
> 
>> 282: long size = length - position;
>> 283: if (size > (long)Integer.MAX_VALUE)
>> 284: throw new OutOfMemoryError("Required array size too 
>> large");
> 
> What do you think of adding "length, position, and size" to the exception 
> message?

We usually don't do that for OutOfMemoryError because concatenation implies 
allocation

-

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


Re: RFR: 8265137: java.util.Random suddenly has new public methods nowhere documented [v6]

2021-04-22 Thread Rémi Forax
On Wed, 21 Apr 2021 13:13:16 GMT, Jim Laskey  wrote:

>> Move makeXXXSpilterator from public (@hidden) to protected. No API ch
>
> Jim Laskey 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 branch 'master' into 8265137
>  - Remove @hidden
>  - Correct the hierarchy of Random
>  - Remove extraneous references to makeXXXSpliterator
>  - Move makeXXXSpliterator methods to RandomSupport
>  - change static final from 'proxy' to 'PROXY'
>  - Make makeXXXSpliterator final
>  - Move makeXXXSpilterator from public (@hidden) to protected. No API change.

Looks good

+1

-

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


Re: RFR: 8265137: java.util.Random suddenly has new public methods nowhere documented [v2]

2021-04-14 Thread Rémi Forax
On Wed, 14 Apr 2021 12:27:55 GMT, Jim Laskey  wrote:

>> Move makeXXXSpilterator from public (@hidden) to protected. No API ch
>
> Jim Laskey has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Make makeXXXSpliterator final

I don't see the point of having those methods virtual, they can be public 
static in RandomSupport given that there is only one implementation (the one 
with an if ... instanceof).
Also the static final proxy should be spelled PROXY.

-

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


Re: RFR: 8263087: Add a MethodHandle combinator that switches over a set of MethodHandles

2021-04-09 Thread Rémi Forax
On Fri, 9 Apr 2021 19:57:10 GMT, Jorn Vernee  wrote:

>>> yes, for all the switches, pattern-switch, enum-switch but not for the 
>>> string switch which requires a lookup switch.
>> Can you outline how to use the tableswitch combinator in the case of a 
>> switch on strings ?
>> 
>> Jan Lahoda has made several good examples of that: 
>> https://github.com/lahodaj/jdk/blob/switch-bootstrap/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java
>>  i.e. several filtering strategies for translating a String into a table 
>> index (which can then be fed to `tableswitch`)
>> 
>> I ran some benchmarks:
>> 
>> ![results](http://cr.openjdk.java.net/~jvernee/StringSwitch_10.svg)
>> 
>> Here, 'legacy' is what C2 does with `lookupswitch`.
>> 
>> Maybe it's worth it to include such an example & benchmark in this patch as 
>> well (show off how to emulate `lookupswitch`)
>
> I've uploaded a benchmark that simulates a lookup switch using the 
> tableSwitch combinator as well, using a HashMap lookup as a filter: 
> https://github.com/openjdk/jdk/commit/a7157eb0ef1b7190aabfb2689539801c6692bbae
> 
> For that particular key set (the same as from the graph above), HashMap is 
> faster:
> 
> Benchmark  Mode  Cnt   Score   
> Error  Units
> MethodHandlesEmulateLookupSwitch.emulatedLookupSwitch  avgt   30  19.450 � 
> 0.079  ms/op
> MethodHandlesEmulateLookupSwitch.nativeLookupSwitchavgt   30  25.370 � 
> 0.159  ms/op
> 
> But, I've found it really depends on the key set. However, this is mostly to 
> demonstrate that emulation can have competitive performance with native 
> `lookupswitch`. e.g. to get constant folding for constant inputs another 
> filter has to be used, since C2 can not see through the HashMap lookups.

Ok, let restart from the beginning,
you have two strategy to de-sugar a switch,
- if what you do after the case do not mutate any variables, you can desugar 
each case to a method more or less like a lambda (it's not exactly like a 
lambda because there is no capture) and you have an indy in front that will 
call the right method handles
- you have a front end, with an indy that associate the object to an int and a 
backend which is tableswitch in the bytecode

The first strategy is an optimization, it will get you good performance by 
example if you compare a switch on a hirerachy on types and the equivalent 
method call. But you can not use that strategy for all switch, it's more an 
optimization.
The second strategy let you encode any switches.

The tests above are using the first strategy, which I think is not what we 
should implement by default given that it doesn't work will all cases. In the 
particular case of a switch on string, javac generates two switches, the front 
one and the back one, if we want to compare, we should implement the second 
strategy, so indy or the equivalent constant handle should take a String as 
parameter and return an int.

On the test themselves, for the hash, the Map should be directly bound, it will 
be more efficient, the asm version doesn't not appear in the graphics and there 
is a missing strategy that is using a MutableCallSite to switch from the a 
cascade of guards using the real values (store the String value even if it goes 
to `default`) and then switch to a lookup switch which i've found is the 
optimal strategy in real code (it works a lot like a bi-morphic cache but on 
string values instead of on classes).

-

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


Re: RFR: 8263668: Update java.time to use instanceof pattern variable

2021-03-24 Thread Rémi Forax
On Wed, 24 Mar 2021 09:56:16 GMT, Patrick Concannon  
wrote:

> Hi,
> 
> Could someone please review my code for updating the code in the `java.time` 
> package to make use of the `instanceof` pattern variable?
> 
> Kind regards,
> Patrick

src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java line 
168:

> 166: private static final TemporalQuery QUERY_REGION_ONLY = 
> (temporal) -> {
> 167: ZoneId zone = temporal.query(TemporalQueries.zoneId());
> 168: return (zone != null && (!(zone instanceof ZoneOffset)) ? zone : 
> null);

i find this code hard to read
`return (zone != null && (!(zone instanceof ZoneOffset))) ? zone : null;`
seems better`

-

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


Re: RFR: 8263668: Update java.time to use instanceof pattern variable

2021-03-24 Thread Rémi Forax
On Wed, 24 Mar 2021 09:56:16 GMT, Patrick Concannon  
wrote:

> Hi,
> 
> Could someone please review my code for updating the code in the `java.time` 
> package to make use of the `instanceof` pattern variable?
> 
> Kind regards,
> Patrick

src/java.base/share/classes/java/time/LocalDateTime.java line 1686:

> 1684: public long until(Temporal endExclusive, TemporalUnit unit) {
> 1685: LocalDateTime end = LocalDateTime.from(endExclusive);
> 1686: if (unit instanceof ChronoUnit u) {

`chronoUnit` is perhaps a better variable name than `u`

src/java.base/share/classes/java/time/LocalTime.java line 1412:

> 1410: if (unit instanceof ChronoUnit u) {
> 1411: long nanosUntil = end.toNanoOfDay() - toNanoOfDay();  // no 
> overflow
> 1412: switch (u) {

same comment as above

src/java.base/share/classes/java/time/MonthDay.java line 448:

> 446: public long getLong(TemporalField field) {
> 447: if (field instanceof ChronoField f) {
> 448: switch (f) {

as above, `chronoField` instead of `f`

src/java.base/share/classes/java/time/OffsetDateTime.java line 599:

> 597: @Override
> 598: public int get(TemporalField field) {
> 599: if (field instanceof ChronoField f) {

see above

src/java.base/share/classes/java/time/OffsetDateTime.java line 636:

> 634: @Override
> 635: public long getLong(TemporalField field) {
> 636: if (field instanceof ChronoField f) {

see above

src/java.base/share/classes/java/time/OffsetTime.java line 1182:

> 1180: OffsetTime end = OffsetTime.from(endExclusive);
> 1181: if (unit instanceof ChronoUnit u) {
> 1182: long nanosUntil = end.toEpochNano() - toEpochNano();  // no 
> overflow

see above

src/java.base/share/classes/java/time/Year.java line 500:

> 498: public long getLong(TemporalField field) {
> 499: if (field instanceof ChronoField f) {
> 500: switch (f) {

see above

src/java.base/share/classes/java/time/Year.java line 711:

> 709: @Override
> 710: public Year plus(long amountToAdd, TemporalUnit unit) {
> 711: if (unit instanceof ChronoUnit u) {

see above

src/java.base/share/classes/java/time/Year.java line 917:

> 915: public long until(Temporal endExclusive, TemporalUnit unit) {
> 916: Year end = Year.from(endExclusive);
> 917: if (unit instanceof ChronoUnit u) {

see above

src/java.base/share/classes/java/time/YearMonth.java line 488:

> 486: @Override
> 487: public long getLong(TemporalField field) {
> 488: if (field instanceof ChronoField f) {

see above

src/java.base/share/classes/java/time/YearMonth.java line 808:

> 806: @Override
> 807: public YearMonth plus(long amountToAdd, TemporalUnit unit) {
> 808: if (unit instanceof ChronoUnit u) {

see above

src/java.base/share/classes/java/time/YearMonth.java line 1049:

> 1047: public long until(Temporal endExclusive, TemporalUnit unit) {
> 1048: YearMonth end = YearMonth.from(endExclusive);
> 1049: if (unit instanceof ChronoUnit u) {

see above

src/java.base/share/classes/java/time/ZonedDateTime.java line 816:

> 814: @Override  // override for Javadoc and performance
> 815: public int get(TemporalField field) {
> 816: if (field instanceof ChronoField f) {

see above

src/java.base/share/classes/java/time/ZonedDateTime.java line 853:

> 851: @Override
> 852: public long getLong(TemporalField field) {
> 853: if (field instanceof ChronoField f) {

see above

src/java.base/share/classes/java/time/chrono/ChronoLocalDateImpl.java line 380:

> 378: Objects.requireNonNull(endExclusive, "endExclusive");
> 379: ChronoLocalDate end = getChronology().date(endExclusive);
> 380: if (unit instanceof ChronoUnit u) {

see above

src/java.base/share/classes/java/time/chrono/ChronoLocalDateTimeImpl.java line 
379:

> 377: if (unit.isTimeBased()) {
> 378: long amount = end.getLong(EPOCH_DAY) - 
> date.getLong(EPOCH_DAY);
> 379: switch (u) {

see above

src/java.base/share/classes/java/time/chrono/ChronoZonedDateTime.java line 198:

> 196: @Override
> 197: default int get(TemporalField field) {
> 198: if (field instanceof ChronoField f) {

see above

src/java.base/share/classes/java/time/chrono/ChronoZonedDateTime.java line 212:

> 210: @Override
> 211: default long getLong(TemporalField field) {
> 212: if (field instanceof ChronoField f) {

see above

-

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


Re: RFR: 8263358: Update java.lang to use instanceof pattern variable [v5]

2021-03-15 Thread Rémi Forax
On Mon, 15 Mar 2021 11:39:20 GMT, Jan Lahoda  wrote:

>> We have considered generics, that why parameterized generics with another 
>> type arguments are forbidden, but i think we have forgotten raw types.
>
> I don't think that cast from `Object` to a raw type is unchecked, so as error 
> does not seem warranted to me.
> 
> However, I agree javac should produce the rawtype warning for rawtypes in 
> pattern matching instanceof, because we are introducing a new variable (and 
> casting). I've filled:
> https://bugs.openjdk.java.net/browse/JDK-8263590
> 
> Note the non-pattern matching instanceof does not produce the rawtype 
> warning, and I don't think it should produce it.

yes,
javac should emit a warning in that case, that also the answer of Brian.

https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-March/002925.html

-

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


Re: RFR: 8263358: Update java.lang to use instanceof pattern variable [v5]

2021-03-15 Thread Rémi Forax
On Mon, 15 Mar 2021 11:01:48 GMT, Pavel Rappo  wrote:

>> The problem is that `desc` is a raw type and raw types doesn't play well 
>> with the rest of the language (in particular with inference).
>> 
>> I think it's a bug in javac, it should not even raise a warning but an error.
>> But the spec is not fully clear.
>> 
>> The spec says that the narrow conversion should not be unchecked
>> https://docs.oracle.com/javase/specs/jls/se15/preview/specs/patterns-instanceof-jls.html#jls-14.30.2
>> it depends if you consider the raw conversion as unchecked or not.
>
>> I think it's a bug in javac, it should not even raise a warning but an error.
>> But the spec is not fully clear.
> 
> If you think that it's a bug, consider providing feedback to authors of JEP 
> 394:
> 
>> Other refinements may be incorporated based on further feedback.
> 
> I find it hard to believe that authors didn't consider generic use case (even 
> though JEP 394 doesn't have examples of that).

We have considered generics, that why parameterized generics with another type 
arguments are forbidden, but i think we have forgotten raw types.

-

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


Re: RFR: 8263358: Update java.lang to use instanceof pattern variable [v5]

2021-03-15 Thread Rémi Forax
On Mon, 15 Mar 2021 10:18:26 GMT, Pavel Rappo  wrote:

>> src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java line 
>> 360:
>> 
>>> 358: public final boolean equals(Object o) {
>>> 359: if (this == o) return true;
>>> 360: return (o instanceof DynamicConstantDesc desc)
>> 
>> should be
>>   `(o instanceof DynamicConstantDesc desc)`
>
> I noticed that too initially. However, `javac` does not seem to produce a 
> "rawtypes" warning. Which makes sense, if you think about it.

The problem is that `desc` is a raw type and raw types doesn't play well with 
the rest of the language (in particular with inference).

I think it's a bug in javac, it should not even raise a warning but an error.
But the spec is not fully clear.

The spec says that the narrow conversion should not be unchecked
https://docs.oracle.com/javase/specs/jls/se15/preview/specs/patterns-instanceof-jls.html#jls-14.30.2
it depends if you consider the raw conversion as unchecked or not.

-

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


Re: RFR: 8263358: Update java.lang to use instanceof pattern variable [v5]

2021-03-15 Thread Rémi Forax
On Mon, 15 Mar 2021 09:21:22 GMT, Patrick Concannon  
wrote:

>> Hi,
>> 
>> Could someone please review my code for updating the code in the `java.lang` 
>> package to make use of the `instanceof` pattern variable?
>> 
>> Kind regards,
>> Patrick
>
> Patrick Concannon has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   8263358: Refactored missed equals method

src/java.base/share/classes/java/lang/StackTraceElement.java line 413:

> 411: && Objects.equals(moduleName, e.moduleName)
> 412: && Objects.equals(moduleVersion, e.moduleVersion)
> 413: && e.declaringClass.equals(declaringClass)

testing the declaring class and the line number should be done first given they 
are primitive values, it will be a little more efficient if two 
StackTraceElement are not equals and one is using non interned String.
  return (obj instanceof StackTraceElement e)
 && e.lineNumber == lineNumber
 && e.declaringClass == declaringClass
 && ...

-

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


Re: RFR: 8263358: Update java.lang to use instanceof pattern variable [v5]

2021-03-15 Thread Rémi Forax
On Mon, 15 Mar 2021 09:21:22 GMT, Patrick Concannon  
wrote:

>> Hi,
>> 
>> Could someone please review my code for updating the code in the `java.lang` 
>> package to make use of the `instanceof` pattern variable?
>> 
>> Kind regards,
>> Patrick
>
> Patrick Concannon has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   8263358: Refactored missed equals method

src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java line 
360:

> 358: public final boolean equals(Object o) {
> 359: if (this == o) return true;
> 360: return (o instanceof DynamicConstantDesc desc)

should be
  `(o instanceof DynamicConstantDesc desc)`

-

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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2021-03-15 Thread Rémi Forax
On Wed, 18 Nov 2020 13:45:46 GMT, Jim Laskey  wrote:

>> Need rebase
>
> Created new PR because of forced push: 
> https://github.com/openjdk/jdk/pull/1292

LGTM

-

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


Re: RFR: 8263102: Expand documention of Method.isBridge [v3]

2021-03-09 Thread Rémi Forax
On Tue, 9 Mar 2021 19:13:24 GMT, Joe Darcy  wrote:

>> src/java.base/share/classes/java/lang/reflect/Method.java line 589:
>> 
>>> 587:  * different return type, the virtual machine does not.
>>> 588:  * A
>>> 589:  * common case where covariant overrides are used is for a {@link
>> 
>> I think the example should be clearer because here, you don't show the code 
>> of EnumSet.clone().
>> I wonder if it's not easier if all the code is visible
>>   interface I {
>> Object m();
>>   }
>>   class A implements I {
>> String m() { return "hello"; }
>>   }
>> so you can explain that the VM do the dispatch on I::m()Object so the 
>> compiler has to insert a method A::m()Object,
>> the bridge method with this pseudo-code
>>   class A implements I {
>> /* bridge */ Object m() { return m(); } // calls m()String
>> String m()  { return "hello"; }
>>   }
>
> Hi Remi,
> 
> Thanks for the feedback. I did consider that kind of approach of an example 
> from scratch. I judged referencing instances of bridge methods in the base 
> module to be helpful to demonstrate it wasn't too esoteric of a feature in 
> terms of it is something you, as a developer, may already have seen. Also, 
> given the likely audience of the reading Class.isBridge, I didn't think a 
> stand-alone example was warranted.

@jddarcy, the problem i see is that `EnumSet` is not used a lot and `clone` has 
another layer of complexity because of CloneNotSupportedException, etc.
So i'm not sure that using EnumSet.clone() is the right example here.

Perhaps String.compareTo()/Comparable.compareTo() is a better example ? But 
generics are in the middle too.

-

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


Re: RFR: 8263102: Expand documention of Method.isBridge [v3]

2021-03-08 Thread Rémi Forax
On Tue, 9 Mar 2021 03:27:29 GMT, Joe Darcy  wrote:

>> The existing documentation of Method.isBridge isn't terribly helpful to the 
>> reader. This RFE proposes to given a common example of how bridge methods 
>> are used. The JLS does *not* have a section discussing bridge methods in 
>> detail; bridge methods are a compilation technique for lowering the Java 
>> language to the JVM, they are not a language feature per se. The example 
>> given is not exhaustive; there can be and are other uses of bridge methods.
>> 
>> Once the text is agreed to; I'll update the copyright year as well.
>
> Joe Darcy has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Respond to review feedback.

src/java.base/share/classes/java/lang/reflect/Method.java line 589:

> 587:  * different return type, the virtual machine does not.
> 588:  * A
> 589:  * common case where covariant overrides are used is for a {@link

I think the example should be clearer because here, you don't show the code of 
EnumSet.clone().
I wonder if it's not easier if all the code is visible
  interface I {
Object m();
  }
  class A implements I {
String m() { return "hello"; }
  }
so you can explain that the VM do the dispatch on I::m()Object so the compiler 
has to insert a method A::m()Object,
the bridge method with this pseudo-code
  class A implements I {
/* bridge */ Object m() { return m(); } // calls m()String
String m()  { return "hello"; }
  }

-

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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators

2021-02-26 Thread Rémi Forax
On Fri, 26 Feb 2021 13:13:19 GMT, Jim Laskey  wrote:

>> Stayin' alive
>
> Looking for some final code reviews.

I still don't like the fact that the factory uses reflection but i don't see 
how to do better

-

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


Re: RFR: 8261880: Change nested classes in java.base to static nested classes where possible [v2]

2021-02-17 Thread Rémi Forax
On Wed, 17 Feb 2021 17:24:50 GMT, Claes Redestad  wrote:

>> For static methods, since in java language you cannot declare static method 
>> in instance inner classes, I'd say making them static makes more sense 
>> language-wise. Also making them static reduces compiler synthetic instance 
>> field and constructors.
>
> Incidentally, Java-the-language allows static methods in inner instance 
> classes since JDK 16. And I'm not sure this was ever a restriction at the 
> JVMS level since we've been generating static methods (using ASM) into these 
> inner instance classes since at least JDK 9.

Inner classes doesn't really exist for the JVM, it's just an attribute (in 
fact, a pair of attributes) that is read/write by javac (it's very similar to 
the way generics work).
So it is Ok to have static methods in inner classes since Java 1.1 from the JVM 
POV with the caveat that you may not be all to call them from Java-the-language.
Also since Java 11, inner classes are also nestmate and those attributes 
(NestHost/NestMembers) change the behavior of the VM.

-

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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v17]

2021-02-16 Thread Rémi Forax
On Tue, 16 Feb 2021 14:03:56 GMT, Jim Laskey  wrote:

>> src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java line 
>> 1548:
>> 
>>> 1546:  * @return a stream of (pseudo)randomly chosen {@code int} 
>>> values
>>> 1547:  */
>>> 1548: 
>> 
>> Is `@Override` intentionally omitted?
>
> The interface method is a default method, so not technically an override.

It's not an override but @Override has a broader semantics than just overriding 
an existing method.
Given that it helps to understand that this method is part of a larger 
algorithm, i think this method should be tagged with @Override

-

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


Re: RFR: 8193031: Collections.addAll is likely to perform worse than Collection.addAll [v2]

2020-12-17 Thread Rémi Forax
On Thu, 17 Dec 2020 11:03:45 GMT, Сергей Цыпанов 
 wrote:

>> ok, it means there is a bug in the compiler, the analysis done for unsafe 
>> varargs (with -Xlint:varargs) doesn't check that the called method (here 
>> Arrays.asList()) is tagged with @SafeVarargs.
>
> Should I then wait for the fix of that bug to remove `@SupressWarnings`?

I don't think so, the code is fine, for me.

-

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


Re: RFR: 8193031: Collections.addAll is likely to perform worse than Collection.addAll [v2]

2020-12-17 Thread Rémi Forax
On Thu, 17 Dec 2020 10:45:17 GMT, Сергей Цыпанов 
 wrote:

>> src/java.base/share/classes/java/util/Collections.java line 5589:
>> 
>>> 5587:  */
>>> 5588: @SafeVarargs
>>> 5589: @SuppressWarnings("varargs")
>> 
>> I don't think you need a SuppressWarnings here
>
> Hi, without this I get failed build:
> Compiling 3057 files for java.base
> Compiling 89 properties into resource bundles for java.desktop
> 
> return c.addAll(Arrays.asList(elements));
>   ^
> error: warnings found and -Werror specified
> 1 error
> 1 warning
> make[3]: *** 
> [/home/s.tsypanov/IdeaProjects/jdk-github/build/linux-x86_64-server-release/jdk/modules/java.base/_the.java.base_batch]
>  Error 1
> CompileJavaModules.gmk:604: recipe for target 
> '/home/s.tsypanov/IdeaProjects/jdk-github/build/linux-x86_64-server-release/jdk/modules/java.base/_the.java.base_batch'
>  failed
> make[2]: *** [java.base-java] Error 2
> make[2]: *** Waiting for unfinished jobs
> make/Main.gmk:193: recipe for target 'java.base-java' failed

ok, it means there is a bug in the compiler, the analysis done for unsafe 
varargs (with -Xlint:varargs) doesn't check that the called method (here 
Arrays.asList()) is tagged with @SafeVarargs.

-

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


Re: RFR: 8193031: Collections.addAll is likely to perform worse than Collection.addAll

2020-12-17 Thread Rémi Forax
On Thu, 17 Dec 2020 10:15:23 GMT, Сергей Цыпанов 
 wrote:

>> Hello, I feel like this was previously discussed in 
>> https://mail.openjdk.java.net/pipermail/core-libs-dev/ but since I cannot 
>> find original mail I post this here.
>> 
>> Currently `Collections.addAll()` is implemented and documented as:
>> /**
>>  * ...
>>  * The behavior of this convenience method is identical to that of
>>  * {@code c.addAll(Arrays.asList(elements))}, but this method is likely
>>  * to run significantly faster under most implementations.
>>  */
>> @SafeVarargs
>> public static  boolean addAll(Collection c, T... elements) 
>> {
>> boolean result = false;
>> for (T element : elements)
>> result |= c.add(element);
>> return result;
>> }
>> 
>> But it practice the notation `this method is likely to run significantly 
>> faster under most implementations` is completely wrong. When I take this 
>> [benchmark](https://github.com/stsypanov/benchmarks/blob/master/benchmark-runners/src/main/java/com/luxoft/logeek/benchmark/collection/CollectionsAddAllVsAddAllBenchmark.java)
>>  and run it on JDK 14 I get the following results:
>>(collection)  (size)  
>> Score Error   Units
>> addAllArrayList  10  
>>  37.9 ± 1.9   ns/op
>> addAllArrayList 100  
>>  83.8 ± 3.4   ns/op
>> addAllArrayList1000  
>> 678.2 ±23.0   ns/op
>> collectionsAddAll ArrayList  10  
>>  50.9 ± 1.1   ns/op
>> collectionsAddAll ArrayList 100  
>> 751.4 ±47.4   ns/op
>> collectionsAddAll ArrayList1000 
>> 8839.8 ±   710.7   ns/op
>> 
>> addAll  HashSet  10  
>> 128.4 ± 5.9   ns/op
>> addAll  HashSet 100 
>> 1864.2 ±   102.4   ns/op
>> addAll  HashSet1000
>> 16615.5 ±  1202.6   ns/op
>> collectionsAddAll   HashSet  10  
>> 172.8 ± 6.0   ns/op
>> collectionsAddAll   HashSet 100 
>> 2355.8 ±   195.4   ns/op
>> collectionsAddAll   HashSet1000
>> 20364.7 ±  1164.0   ns/op
>> 
>> addAll   ArrayDeque  10  
>>  54.0 ± 0.4   ns/op
>> addAll   ArrayDeque 100  
>> 319.7 ± 2.5   ns/op
>> addAll   ArrayDeque1000 
>> 3176.9 ±22.2   ns/op
>> collectionsAddAllArrayDeque  10  
>>  66.5 ± 1.4   ns/op
>> collectionsAddAllArrayDeque 100  
>> 808.1 ±55.9   ns/op
>> collectionsAddAllArrayDeque1000 
>> 5639.6 ±   240.9   ns/op
>> 
>> addAll CopyOnWriteArrayList  10  
>>  18.0 ± 0.7   ns/op
>> addAll CopyOnWriteArrayList 100  
>>  39.4 ± 1.7   ns/op
>> addAll CopyOnWriteArrayList1000  
>> 371.1 ±17.0   ns/op
>> collectionsAddAll  CopyOnWriteArrayList  10  
>> 251.9 ±18.4   ns/op
>> collectionsAddAll  CopyOnWriteArrayList 100 
>> 3405.9 ±   304.8   ns/op
>> collectionsAddAll  CopyOnWriteArrayList1000   
>> 247496.8 ± 23502.3   ns/op
>> 
>> addAllConcurrentLinkedDeque  10  
>>  81.4 ± 2.8   ns/op
>> addAllConcurrentLinkedDeque 100  
>> 609.1 ±26.4   ns/op
>> addAllConcurrentLinkedDeque1000 
>> 4494.5 ±   219.3   ns/op
>> collectionsAddAll ConcurrentLinkedDeque  10  
>> 189.8 ± 2.5   ns/op
>> collectionsAddAll ConcurrentLinkedDeque 100 
>> 1660.0 ±62.0   ns/op
>> collectionsAddAll ConcurrentLinkedDeque1000
>> 17649.2 ±   300.9   ns/op
>> 
>> addAll:·gc.alloc.rate.normArrayList  10  
>> 160.0 ± 0.0B/op
>> addAll:·gc.alloc.rate.normArrayList 100  
>> 880.0 ± 0.0B/op
>> addAll:·gc.alloc.rate.normArrayList1000 
>> 8080.3 ± 0.0B/op
>> collectionsAddAll:·gc.alloc.rate.norm ArrayList  10  
>>  80.0 ± 0.0B/op
>> 

Re: RFR: 8193031: Collections.addAll is likely to perform worse than Collection.addAll [v2]

2020-12-17 Thread Rémi Forax
On Thu, 17 Dec 2020 10:33:05 GMT, Сергей Цыпанов 
 wrote:

>> Hello, I feel like this was previously discussed in 
>> https://mail.openjdk.java.net/pipermail/core-libs-dev/ but since I cannot 
>> find original mail I post this here.
>> 
>> Currently `Collections.addAll()` is implemented and documented as:
>> /**
>>  * ...
>>  * The behavior of this convenience method is identical to that of
>>  * {@code c.addAll(Arrays.asList(elements))}, but this method is likely
>>  * to run significantly faster under most implementations.
>>  */
>> @SafeVarargs
>> public static  boolean addAll(Collection c, T... elements) 
>> {
>> boolean result = false;
>> for (T element : elements)
>> result |= c.add(element);
>> return result;
>> }
>> 
>> But it practice the notation `this method is likely to run significantly 
>> faster under most implementations` is completely wrong. When I take this 
>> [benchmark](https://github.com/stsypanov/benchmarks/blob/master/benchmark-runners/src/main/java/com/luxoft/logeek/benchmark/collection/CollectionsAddAllVsAddAllBenchmark.java)
>>  and run it on JDK 14 I get the following results:
>>(collection)  (size)  
>> Score Error   Units
>> addAllArrayList  10  
>>  37.9 ± 1.9   ns/op
>> addAllArrayList 100  
>>  83.8 ± 3.4   ns/op
>> addAllArrayList1000  
>> 678.2 ±23.0   ns/op
>> collectionsAddAll ArrayList  10  
>>  50.9 ± 1.1   ns/op
>> collectionsAddAll ArrayList 100  
>> 751.4 ±47.4   ns/op
>> collectionsAddAll ArrayList1000 
>> 8839.8 ±   710.7   ns/op
>> 
>> addAll  HashSet  10  
>> 128.4 ± 5.9   ns/op
>> addAll  HashSet 100 
>> 1864.2 ±   102.4   ns/op
>> addAll  HashSet1000
>> 16615.5 ±  1202.6   ns/op
>> collectionsAddAll   HashSet  10  
>> 172.8 ± 6.0   ns/op
>> collectionsAddAll   HashSet 100 
>> 2355.8 ±   195.4   ns/op
>> collectionsAddAll   HashSet1000
>> 20364.7 ±  1164.0   ns/op
>> 
>> addAll   ArrayDeque  10  
>>  54.0 ± 0.4   ns/op
>> addAll   ArrayDeque 100  
>> 319.7 ± 2.5   ns/op
>> addAll   ArrayDeque1000 
>> 3176.9 ±22.2   ns/op
>> collectionsAddAllArrayDeque  10  
>>  66.5 ± 1.4   ns/op
>> collectionsAddAllArrayDeque 100  
>> 808.1 ±55.9   ns/op
>> collectionsAddAllArrayDeque1000 
>> 5639.6 ±   240.9   ns/op
>> 
>> addAll CopyOnWriteArrayList  10  
>>  18.0 ± 0.7   ns/op
>> addAll CopyOnWriteArrayList 100  
>>  39.4 ± 1.7   ns/op
>> addAll CopyOnWriteArrayList1000  
>> 371.1 ±17.0   ns/op
>> collectionsAddAll  CopyOnWriteArrayList  10  
>> 251.9 ±18.4   ns/op
>> collectionsAddAll  CopyOnWriteArrayList 100 
>> 3405.9 ±   304.8   ns/op
>> collectionsAddAll  CopyOnWriteArrayList1000   
>> 247496.8 ± 23502.3   ns/op
>> 
>> addAllConcurrentLinkedDeque  10  
>>  81.4 ± 2.8   ns/op
>> addAllConcurrentLinkedDeque 100  
>> 609.1 ±26.4   ns/op
>> addAllConcurrentLinkedDeque1000 
>> 4494.5 ±   219.3   ns/op
>> collectionsAddAll ConcurrentLinkedDeque  10  
>> 189.8 ± 2.5   ns/op
>> collectionsAddAll ConcurrentLinkedDeque 100 
>> 1660.0 ±62.0   ns/op
>> collectionsAddAll ConcurrentLinkedDeque1000
>> 17649.2 ±   300.9   ns/op
>> 
>> addAll:·gc.alloc.rate.normArrayList  10  
>> 160.0 ± 0.0B/op
>> addAll:·gc.alloc.rate.normArrayList 100  
>> 880.0 ± 0.0B/op
>> addAll:·gc.alloc.rate.normArrayList1000 
>> 8080.3 ± 0.0B/op
>> collectionsAddAll:·gc.alloc.rate.norm ArrayList  10  
>>  80.0 ± 0.0B/op
>> 

Re: RFR: 8255542: Attribute length of Module, ModulePackages and other attributes is ignored [v2]

2020-12-03 Thread Rémi Forax
On Thu, 3 Dec 2020 15:52:35 GMT, Daniel Fuchs  wrote:

>> src/java.base/share/classes/jdk/internal/module/ModuleInfo.java line 1203:
>> 
>>> 1201: @Override
>>> 1202: public String readUTF() throws IOException {
>>> 1203: return DataInputStream.readUTF(this);
>> 
>> If i understand correctly the code, I believe readUTF should change a 
>> boolean field named `countCanNotBeTrackedAnymore` from false to true, and in 
>> the method `count()`,  `countCanNotBeTrackedAnymore` has to be checked and 
>> throws an ISE before returning `count`
>
> Hi Rémi, I do not think that that is required. `DataInputStream.readUTF` will 
> call back into `this` to do the reading so the `count` should be properly 
> incremented? Or maybe I'm missing something. Best regards!

Thanks,
i should have read the code more carefully.

-

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


Re: RFR: 8255542: Attribute length of Module, ModulePackages and other attributes is ignored [v2]

2020-12-03 Thread Rémi Forax
On Thu, 3 Dec 2020 09:58:16 GMT, Alan Bateman  wrote:

>> The attribute_length of known Module attributes in the module-info.class 
>> is currently ignored. It should be checked and the class rejected if the 
>> attribute length doesn't exactly match the length of the info in the 
>> attribute.
>> 
>> There are several ways to fix this. I initially limited the reading of the 
>> attribute_info to the attribute length but this resulted in confusing 
>> exception messages as the attribute appears truncated. The exception 
>> messages are clearer when it checks that the attribute length corresponds to 
>> the number of bytes read.
>
> Alan Bateman 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 11 additional 
> commits since the last revision:
> 
>  - Restructure check to make it more obvious that it doesn't overflow
>  - Merge
>  - Merge
>  - Merge
>  - Trailing whitespace
>  - Expand test to Module attribute
>  - Merge
>  - Test cleanup
>  - Add test
>  - Merge
>  - ... and 1 more: 
> https://git.openjdk.java.net/jdk/compare/914dd7e9...f15dbb1b

src/java.base/share/classes/jdk/internal/module/ModuleInfo.java line 1203:

> 1201: @Override
> 1202: public String readUTF() throws IOException {
> 1203: return DataInputStream.readUTF(this);

If i understand correctly the code, I believe readUTF should change a boolean 
field named `countCanNotBeTrackedAnymore` from false to true, and in the method 
`count()`,  `countCanNotBeTrackedAnymore` has to be checked and throws an ISE 
before returning `count`

-

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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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 Object>)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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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 RandomGenerator>> factoryMap;

should be FACTORY_MAP given that it's a static field

-

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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8248862: Implement Enhanced Pseudo-Random Number Generators [v3]

2020-11-25 Thread Rémi Forax
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


Re: RFR: 8180352: Add Stream.toList() method [v3]

2020-11-21 Thread Rémi Forax
On Wed, 4 Nov 2020 09:21:12 GMT, Tagir F. Valeev  wrote:

>> src/java.base/share/classes/java/util/stream/Stream.java line 1192:
>> 
>>> 1190: @SuppressWarnings("unchecked")
>>> 1191: default List toList() {
>>> 1192: return (List) Collections.unmodifiableList(new 
>>> ArrayList<>(Arrays.asList(this.toArray(;
>> 
>> Why can't we return `listFromTrustedArrayNullsAllowed` here as in 
>> `ReferencePipeline`?
>> Or at least, we should avoid unnecessary copying of arrays. See [how this is 
>> done](https://github.com/amaembo/streamex/blob/master/src/main/java/one/util/streamex/AbstractStreamEx.java#L1313)
>>  in StreamEx.
>
> `listFromTrustedArrayNullsAllowed` is clearly not an option, as it will 
> produce shared-secret leaking (see 
> [JDK-8254090](https://bugs.openjdk.java.net/browse/JDK-8254090) for a similar 
> case). StreamEx solution is dirty as it relies on the implementation detail. 
> I believe, OpenJDK team is not very interested in providing optimal 
> implementations for third-party stream implementations, as third-party 
> implementations will likely update by themselves when necessary. At least, my 
> suggestion to make the default `mapMulti` implementation better was declined.

This implementation duplicates the array twice, once in this.toArray() and once 
in the constructor of ArrayList that calls toArray() on Collections.ArrayList.

I'm sure there is a better way

-

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


Re: RFR: 8180352: Add Stream.toList() method [v3]

2020-11-21 Thread Rémi Forax
On Wed, 18 Nov 2020 22:20:26 GMT, Stuart Marks  wrote:

>> This change introduces a new terminal operation on Stream. This looks like a 
>> convenience method for Stream.collect(Collectors.toList()) or 
>> Stream.collect(Collectors.toUnmodifiableList()), but it's not. Having this 
>> method directly on Stream enables it to do what can't easily by done by a 
>> Collector. In particular, it allows the stream to deposit results directly 
>> into a destination array (even in parallel) and have this array be wrapped 
>> in an unmodifiable List without copying.
>> 
>> In the past we've kept most things from the Collections Framework as 
>> implementations of Collector, not directly on Stream, whereas only 
>> fundamental things (like toArray) appear directly on Stream. This is true of 
>> most Collections, but it does seem that List is special. It can be a thin 
>> wrapper around an array; it can handle generics better than arrays; and 
>> unlike an array, it can be made unmodifiable (shallowly immutable); and it 
>> can be value-based. See John Rose's comments in the bug report:
>> 
>> https://bugs.openjdk.java.net/browse/JDK-8180352?focusedCommentId=14133065=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14133065
>> 
>> This operation is null-tolerant, which matches the rest of Streams. This 
>> isn't specified, though; a general statement about null handling in Streams 
>> is probably warranted at some point.
>> 
>> Finally, this method is indeed quite convenient (if the caller can deal with 
>> what this operation returns), as collecting into a List is the most common 
>> stream terminal operation.
>
> Stuart Marks has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Adjust List.copyOf to null-check and copy allowNulls lists.
>   Fix equals, hashCode, indexOf, lastIndexOf to handle nulls properly.
>   Add MOAT tests for new lists; add equals and hashCode tests.

src/java.base/share/classes/java/util/ImmutableCollections.java line 222:

> 220: default:
> 221: return (List) new ListN<>(input, false);
> 222: }

Using a switch expression + arrow (->) here will allow you too factor the cast, 
even if it disappear in the generated bytecode, I think it makes the code more 
readable

-

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


Re: RFR: 8180352: Add Stream.toList() method [v3]

2020-11-21 Thread Rémi Forax
On Thu, 5 Nov 2020 17:26:48 GMT, Stuart Marks  wrote:

>> src/java.base/share/classes/java/util/ImmutableCollections.java line 199:
>> 
>>> 197:  * safely reused as the List's internal storage, avoiding a 
>>> defensive copy. Declared
>>> 198:  * with Object... instead of E... as the parameter type so that 
>>> varargs calls don't
>>> 199:  * accidentally create an array of type other than Object[].
>> 
>> Why would that be a problem? If the resulting list is immutable, then the 
>> actual array type doesn't really matter, right?
>
> It's an implementation invariant that the internal array be Object[]. Having 
> it be something other than Object[] can lead to subtle bugs. See 
> [JDK-6260652](https://bugs.openjdk.java.net/browse/JDK-6260652) for example.

you can still calls the varargs with an already created array
listFromTrustedArray(new String[] { "foo" });

I think at least an assert is missing
assert input.getClass() == Object.class;

-

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


Re: RFR: 8159746: (proxy) Support for default methods

2020-11-20 Thread Rémi Forax
On Fri, 20 Nov 2020 19:51:57 GMT, Mandy Chung  wrote:

>> @plevart I'm okay with this slight performance improvement.
>
> I have a fresh look at the different options we have explored (lots of 
> challenges in finding the right API with security, usability and performance 
> issues to consider).   I agree with Remi that we should keep the design and 
> API simple and makes it easier to invoke default methods with today's Proxy 
> API.We can design a better Proxy API in the future.   
> 
> The options we have explored are:
> 1. static `InvocationHandler::invokeDefault` method
> 2. abstract `DelegatingInvocationHandler` class with a protected 
> `invokeDefault` method
> 3. a new `newProxyInstance` factory method taking a function that produces an 
> invocation handler with the ability to invoke a default method via a 
> `superHandler`
> 
> (1) is very simple API but caller-sensitive.  No other API change.   Access 
> check done at default method invocation time (which is consistent with the 
> core reflection `Method::invoke`).It shares the caller class caching in 
> `Method::checkAccess` which helps the performance. The performance 
> overhead is slightly higher than (2) & (3) which does access check at proxy 
> creation time.
> 
> (2) is simple and I like that the `invokeDefault` can be enforced to be 
> invoked only by the proxy's invocation handler.   However this requires more 
> API changes (including `newProxyInstance`, `getInvocationHandler`, and new 
> unchecked exception type).   (3) is clever but a bit over-rotated (how Alan 
> describes it) to allow it to be expressed in a lambda expression.  If an 
> invocation handler wants to save `superHandler`, it can't assign it to a 
> final field in lambda and would need to workaround it writing to an array 
> element.
> 
> I will go with option (1) -  static `invokeDefault` method [1] unless there 
> is any objection. 
> 
> Here is the specdiff:
>   http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8159746/specdiff/
> 
> [1] 
> http://cr.openjdk.java.net/~mchung/jdk16/webrevs/8159746/api/java.base/java/lang/reflect/InvocationHandler.html#invokeDefault(java.lang.Object,java.lang.reflect.Method,java.lang.Object...)

Hi Mandy,
thanks for taking the time to explore all the different options,

The solution 1 is fine for me.

-

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


Re: RFR: 8186085: (opt) add filter(), flatMap(), and map() methods to OptionalDouble/Int/Long

2020-11-01 Thread Rémi Forax
On Sun, 1 Nov 2020 13:20:20 GMT, Kartik Ohri 
 wrote:

>> Hi !
>> thanks for taking the time to craft that pull request but this is typically 
>> the kind of patch that should be discussed on the mailing list first before 
>> creating a pull request.
>> 
>> There are several issues, one is that we want to retrofit OptionalInt, 
>> OptionalLong, etc to be Optional, Optional as part of project 
>> Valhalla so we don't want to add more methods in the primitive variants of 
>> Optional and Stream to avoid to be blocked later while trying retrofitting 
>> those classes due to these methods.
>> So we know that some methods are missing but we want to know first how the 
>> specialization of generics over primitive types works before adding those 
>> methods.
>> 
>> The second issue is that when you want to change the public API of the JDK, 
>> you have to create a CSR to ask to the CSR guys/girls leaded by Joe Darcy if 
>> the signature and the semantics of the methods you want to add are coherent 
>> with the rest of the API.
>> 
>> I recommend you to start by fixing bugs because those can be fixed by a 
>> simple pull request.
>> 
>> regards,
>> Rémi
>
> Thank you for the suggestions. I'll try fixing some bugs first. Should I 
> close this PR as well or leave it open ?

If it doesn't break your hart too much, yes please.

-

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


Re: RFR: 8186085: (opt) add filter(), flatMap(), and map() methods to OptionalDouble/Int/Long

2020-11-01 Thread Rémi Forax
On Sat, 31 Oct 2020 16:45:06 GMT, Kartik Ohri 
 wrote:

>> Hi all,
>> This PR intends to add filter, map and flatMap methods to the Optional 
>> classes for primitives. The rationale is consistency with the Optional class 
>> for objects and user convenience.
>> Thanks.
>> Regards,
>> Kartik
>
> Kindly review the patch. Thanks in advance!

Hi !
thanks for taking the time to craft that pull request but this is typically the 
kind of patch that should be discussed on the mailing list first before 
creating a pull request.

There are several issues, one is that we want to retrofit OptionalInt, 
OptionalLong, etc to be Optional, Optional as part of project 
Valhalla so we don't want to add more methods in the primitive variants of 
Optional and Stream to avoid to be blocked later while trying retrofitting 
those classes due to these methods.
So we know that some methods are missing but we want to know first how the 
specialization of generics over primitive types works before adding those 
methods.

The second issue is that when you want to change the public API of the JDK, you 
have to create a CSR to ask to the CSR guys/girls leaded by Joe Darcy if the 
signature and the semantics of the methods you want to add are coherent with 
the rest of the API.

I recommend you to start by fixing bugs because those can be fixed by a simple 
pull request.

regards,
Rémi

-

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


Re: RFR: 8159746: (proxy) Support for default methods

2020-10-28 Thread Rémi Forax
On Wed, 28 Oct 2020 19:28:36 GMT, Mandy Chung  wrote:

>> Hi Mandy and Peter,
>> reading your exchanges, i wonder if it's not better to stop trying to add 
>> more and more features to the already clunky java.lang.reflect.Proxy but 
>> instead to move to provide the same set of feature but using an 
>> implementation based on java.lang.invoke.Lookup/MethodHandle.
>> 
>> I propose to introduce a java.lang.invoke.Proxy has a replacement of 
>> java.lang.reflect.Proxy using j.l.i.MethodHandle instead of j.l.r.Method, 
>> the equivalent of the InvocationHandler acting as a linker called once per 
>> the first time a method of the Proxy is called instead of being called each 
>> time a method is called.
>> 
>> Such proxy
>> - has it's security model based on Lookup to define the class,
>>   so no supplementary restrictions on package/module of the interface 
>> implemented
>> - avoid to mix java.lang.reflect API and java.invoke API
>> - is transparent in term of exceptions (ther are propagated without any 
>> wrapping/unwrapping)
>> - can support default methods natively
>> - doesn't requires any caching (the user will be responsible to do the 
>> caching)
>> - is more efficient, actually as efficient as the equivalent written code or 
>> a little more (thanks to @ForceInline)
>
> Hi Remi,
> 
> I appreciate your proposal to modernize Proxy API.   There are several 
> requests for this enhancement to support default methods in Proxy.   Defining 
> a new `java.lang.invoke.Proxy` is a much bigger project that I can't tell 
> when the existing users of `java.lang.reflect.Proxy` will be able to get this 
> default method invocation support.  
> 
> I do agree that this API design has many challenges caused by what you listed 
> above.   Well, I believe we are very close to have a consensus:
> 1. New `newProxyInstance` factory method takes a handler factory doing the 
> access check
> 2. Update `getInvocationHandler` to throw 
> `InaccessibleInvocationHandlerException` if access denied to get an 
> invocation handler associated with the proxy instance
> 
> If this needs more time, I think I will consider to shelf this RFE and come 
> back to it later (and consider your proposal as well).

The trick is that if we know that a class like java.lang.invoke.Proxy may exist,
it means that instead of distorting the j.l.r.Proxy API to increase of few 
percents the performance when calling a default method, you can come with a 
simpler design in term of API that just add an API point to call a default 
method.

Better performance becoming on the the goals of java.lang.invoke.Proxy.

-

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


Re: RFR: 8159746: (proxy) Support for default methods

2020-10-28 Thread Rémi Forax
On Wed, 28 Oct 2020 17:36:40 GMT, Mandy Chung  wrote:

>>> Hi Peter,
>>> 
>>> > Question remains how do we distinguish proxies with old-fassioned 
>>> > InvocationHandlers from proxies with InvocationHandlers having access to 
>>> > super-default-handler. Both kinds of handlers look the same from Proxy's 
>>> > perspective... Perhaps we need a boolean flag in Proxy instance for that, 
>>> > coupled with an overloaded constructor that takes it...
>>> 
>>> I have the Proxy constructor taking both the invocation handler and 
>>> `superHandler` in my 
>>> [mlchung:proxy-default-method-4](https://github.com/mlchung/jdk/tree/proxy-default-method-4)
>>>  branch.
>>> 
>> 
>> Yes, but it is not really useful there. The super handler is captured by the 
>> user invocation handler created in the invocation handler factory function 
>> and it is only used by the user invocation handler. All we need in the proxy 
>> instance is a boolean flag indicating the way the invocation handler was 
>> created (which one of the two overloaded newProxyInstance methods was 
>> called).
>> 
>>> > Problem with this approach is that it is not really useful in the proxy 
>>> > instance. We don't need it in the proxy instance.
>>> 
>>> See above.
>>> 
>>> About the exception thrown: we need to distinguish CCE and NPE thrown by 
>>> the default method vs thrown by arguments incompatible with the method 
>>> signature. In my proxy-default-method-4 branch, I define an internal 
>>> exception type for that. There is an overhead doing the wrapping but it's 
>>> an exception case which performance should not be critical.
>> 
>> To be precise, we need to pass CCE and NPE thrown by the default method 
>> unchanged, but we need to wrap CCE and NPE thrown by the method handle 
>> transformation chain with IllegalArgumentException. Is that what you are 
>> referring to? In that case we need an internal exception type, not exposed 
>> to public API, used just to "tunnel" the exception from the default method 
>> unchanged. That's just implementation detail.
>> 
>> But we have to ask ourselves a question: "Do we want to wrap CCE and NPE 
>> thrown by the method handle transformation chain with 
>> IllegalArgumentException?". We did that in previous variants to mimic the 
>> Method.invoke specification. But now we already departed from that 
>> specification by not wrapping exceptions thrown by the default method with 
>> InvocationTargetException. So we are not obligated to follow the rest of the 
>> Method.invoke specification either. All exception types thrown by method 
>> handle transformation chain (CCE, NPE, IAE) are unchecked exceptions and as 
>> such are not eligible to wrapping with UndeclaredThrowableException by the 
>> Proxy API. So it's just a matter of deciding what is more suitable: to have 
>> more specific exception types (CCE, NPE, IAE) for describing transformation 
>> exceptions or to reduce them to one common type (IAE). In either case those 
>> exception types can also be thrown by the default method and we can't or 
>> even want to distinguish their source. Let's be ho
 nest, all of CCE, NPE, IAE are usually describing the subtle variants of the 
same thing: that the parameters are wrong. Whether this happens in the logic of 
invocation handler, method handle transformation chain or the default method, 
we want those exceptions to propagate out of the invoked proxy method unchanged.
>> 
>> So WDYT?
>
>> Yes, but it is not really useful there. The super handler is captured by the 
>> user invocation handler created in the invocation handler factory function 
>> and it is only used by the user invocation handler. All we need in the proxy 
>> instance is a boolean flag indicating the way the invocation handler was 
>> created (which one of the two overloaded newProxyInstance methods was 
>> called).
> 
> Either way provides the distinction if this proxy class supports default 
> method invocation.   I chose to store the superHandler rather than a boolean 
> that may allow us to do white-box testing (an alternative to the trick in 
> getting the superHandler in spinning another proxy instance).   It's a 
> trivial change  if we prefer to store a boolean field but keep the 
> constructor to take `superHandler` parameter.  I'm fine with it.
> 
>> To be precise, we need to pass CCE and NPE thrown by the default method 
>> unchanged, but we need to wrap CCE and NPE thrown by the method handle 
>> transformation chain with IllegalArgumentException. Is that what you are 
>> referring to? 
> 
> Yes and it's implementation details.  For the specification side, I agree 
> that `InvocationHandler::invoke` throws the exception by the method and no 
> need to wrap it with `InvocationTargetException` .
> 
>> "Do we want to wrap CCE and NPE thrown by the method handle transformation 
>> chain with IllegalArgumentException?".
> 
> I did consider that and propose to go with IAE for simplicity and consistency 
> with the core reflection 

Re: RFR: 8254354: Add an asExact() VarHandle combinator

2020-10-26 Thread Rémi Forax
On Fri, 23 Oct 2020 17:47:36 GMT, Jorn Vernee  wrote:

> Hi,
> 
> This patch adds an asExact() combinator to VarHandle, that will return a new 
> VarHandle that performs exact type checks, similar to 
> MethodHandle::invokeExact, to help developers catch inexact VarHandle usage, 
> which can lead to performance degradation.
> 
> This is implemented using a boolean flag in VarForm. If the flag is set, the 
> exact type of the invocation is checked against the exact type in the 
> VarForm. If there is a mismatch, a WrongMethodTypeException is thrown.
> 
> Other than that, there is also an asGeneric() combinator added that does the 
> inverse operation (thanks to Rémi for the suggestion). I've also added The 
> `@Hidden` annotation to the VarHandleGuards methods, as well as a 
> type-checking helper method called from the generic invocation lambda form, 
> so that the stack trace we get points at the location where the VarHandle is 
> being used.
> 
> Thanks,
> Jorn
> 
> CSR link: https://bugs.openjdk.java.net/browse/JDK-8255375

Looks good to me.

-

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


Re: RFR: 8254354: Add an asExact() VarHandle combinator [v2]

2020-10-26 Thread Rémi Forax
On Mon, 26 Oct 2020 16:34:10 GMT, Paul Sandoz  wrote:

>> The direct use of the enum ordinal is because HotSpot accessing it from the 
>> enum value is (or was) not optimal in C2.
>>  
>> You can avoid the addition of the stable array by doing the following:
>> 
>> public final MethodType accessModeType(AccessMode accessMode) {
>> return accessModeType(accessMode.at.ordinal());
>> }
>> 
>> @ForceInline
>> final MethodType accessModeType(int accessModeOrdinal) {
>> TypesAndInvokers tis = getTypesAndInvokers();
>> MethodType mt = tis.methodType_table[accessModeOrdinal];
>> if (mt == null) {
>> mt = tis.methodType_table[accessModeOrdinal] =
>> accessModeTypeUncached(accessModeOrdinal);
>> }
>> return mt;
>> }
>> 
>> final MethodType accessModeTypeUncached(int accessModeOrdinal) {
>> return 
>> accessModeTypeUncached(AccessMode.values()[accessModeOrdinal]);
>> }
>> It's a little odd going back and forth between the ordinal and the enum 
>> value, but it's all on the slow uncached path, and it avoids some 
>> duplication of code.
>> 
>> I'll take a closer looks at the other areas and respond in another comment.
>
> We can clarify the new methods and tie them closer to method handle 
> semantics. I suggest the names `asExactInvoker` and `asInvoker`, referencing 
> `MethodHandles.exactInvoker` and `MethodHandles.invoker` respectively. (The 
> term "generic" is really reserved for erased method types, and otherwise used 
> internally as the generic invoker.)
> 
> The `VarHandle` documentation already specifies that:
> 
>  * 
>  * Invocation of an access mode method behaves as if an invocation of
>  * {@link MethodHandle#invoke}, where the receiving method handle accepts the
>  * VarHandle instance as the leading argument.  More specifically, the
>  * following, where {@code {access-mode}} corresponds to the access mode 
> method
>  * name:
>  *  {@code
>  * VarHandle vh = ..
>  * R r = (R) vh.{access-mode}(p1, p2, ..., pN);
>  * }
>  * behaves as if:
>  *  {@code
>  * VarHandle vh = ..
>  * VarHandle.AccessMode am = 
> VarHandle.AccessMode.valueFromMethodName("{access-mode}");
>  * MethodHandle mh = MethodHandles.varHandleExactInvoker(
>  *   am,
>  *   vh.accessModeType(am));
>  *
>  * R r = (R) mh.invoke(vh, p1, p2, ..., pN)
>  * }
>  * (modulo access mode methods do not declare throwing of {@code Throwable}).
> ...
> 
>  We will need to adjust this section, i can help, but first let us reach 
> agreement on this approach.

Paul,
an invoker has the MethodHandle (resp. VarHandle) as first argument so it's not 
the same semantics.

-

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


Re: RFR: 8255398: Add a dropReturn MethodHandle combinator [v3]

2020-10-26 Thread Rémi Forax
On Mon, 26 Oct 2020 18:01:04 GMT, John R Rose  wrote:

>> @rose00 My bad. You're right, I realized we could also use `asType` later on 
>> (I did call it out in the CSR), but It's still a bit more wordy than what 
>> I'm proposing.
>> 
>> `dropReturn` seemed like a good choice since we already have 
>> `dropArguments`. WRT changing to `MethodHandle::changeReturnType`, I think 
>> doing that also begs for adding a `MethodHandle::changeParameterType` (with 
>> a single index and varargs overload). But, in that case it seems fair to 
>> just point users at `asType` instead.
>> 
>> In other words; `dropReturn` seems fine to get parity with `dropArguments`, 
>> but `changeReturnType` seems a step too close to `asType` (also since it 
>> implies adding `changeParameterType` as well). So, maybe this RFE is a bust, 
>> and users should use `asType` instead? Or do you think adding both 
>> `changeReturnType` and `changeParameterType`(s) seems worth it? (I'm not so 
>> sure).
>
>> …`dropReturn` seemed like a good choice since we already have 
>> `dropArguments`. WRT changing to `MethodHandle::changeReturnType`...
> 
> That's a very reasonable point.  People might look for `dropRT` after they 
> find `dropAs`.  And `MHs` is designed as a large-ish set of utility methods.
> 
> I agree that adding `MH::changeRT` is a slippery slope; it tends to lift more 
> of the MT API onto MH, and it starts to put new stuff into the smaller MH 
> API; that was my bad.
> 
> But (in the spirit of brainstorming, and agreeing with your present 
> proposal), I'll suggest a separate idea to think about.  Use a HOFP API to 
> give easy access to the entire `MT` API all in one go, by reifying the 
> `MH.type` property as a temporary (lambda argument):
> 
> MethodHandle mapType(MethodHandle mh, UnaryOperator fn) {
>return mh.asType(fn.apply(mh.type()));
> }
> 
> This also suggests a possible argument transform utility, a sort of 
> mini-version of Charlie Nutter's MH builder API:
> 
> MethodHandle mapArguments(MethodHandle mh, 
> UnaryOperator>> fn) {
>   var args = mh.type().argumentList().stream().map(t -> makeArg(t)).asList();
>   args = fn.apply(args);
>   … do stuff to re-weave mh with the resulting argument transforms …
> }
> public sealed interface ArgumentValue {
>   Class type();
>ArgumentValue asType(Class newType);
>   … other stuff for pre-applying MHs … 
> }

instead of mapArguments(), i believe it's better to have a method map on a 
MethodType that takes two mapping functions, one for the return type and one 
for the prameter types.

so one can write:
  MHs.mapType(mh, mt -> mt.map(Function.identity(), t-> t.isPrimitive? t: 
Object.class))
to not change the return type and erase the parameter type to Object if they 
are not primitives

With that, changing the return type to void can be done that way too
  MHs.mapType(mh, mt -> mt.map(__ -> void.class, Function.identity())

-

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


Re: RFR: 8254354: Add an asExact() VarHandle combinator [v2]

2020-10-23 Thread Rémi Forax
On Fri, 23 Oct 2020 18:04:11 GMT, Jorn Vernee  wrote:

>> Hi,
>> 
>> This patch adds an asExact() combinator to VarHandle, that will return a new 
>> VarHandle that performs exact type checks, similar to 
>> MethodHandle::invokeExact, to help developers catch inexact VarHandle usage, 
>> which can lead to performance degradation.
>> 
>> This is implemented using a boolean flag in VarForm. If the flag is set, the 
>> exact type of the invocation is checked against the exact type in the 
>> VarForm. If there is a mismatch, a WrongMethodTypeException is thrown.
>> 
>> Thanks,
>> Jorn
>
> Jorn Vernee has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Make internalName helper method static

src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleGenerator.java
 line 450:

> 448: }
> 449: 
> 450: private String internalName(Class cls) {

should be static, no ?

-

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


  1   2   3   4   >