Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-03 Thread Claes Redestad
On Fri, 3 Jun 2022 16:48:11 GMT, Jorn Vernee  wrote:

>> I'm not so sure. 
>> 
>> First of all we're no worse than before with the defensive copying here. 
>> Second of an optimizing compiler might theoretically be able to see that the 
>> array we get from the toArray is always fresh and not escaping anywhere in 
>> any well-behaved collection, so the clone could be elided. But if not then 
>> both toArray and clone are intrinsified operations that are heavily 
>> optimized and pretty fast even when interpreting, so emulating it with an 
>> external loop might end up taking more time even at peak. While likely 
>> taking longer to reach that peak. Using dumb, shared and common code 
>> (especially things that get JITted early anyhow) is nice in areas that see 
>> most action during startup/warmup.
>
> Ok, please keep it the way it is in your current patch then.

Correction: `toArray` isn't intrinsified, but common `List` implementations are 
likely to implement it with a `System.arraycopy`, which is.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-03 Thread Jorn Vernee
On Fri, 3 Jun 2022 16:43:37 GMT, Claes Redestad  wrote:

>> The same could be done for the public `dropArgumentsToMatch` I think.
>
> I'm not so sure. 
> 
> First of all we're no worse than before with the defensive copying here. 
> Second of an optimizing compiler might theoretically be able to see that the 
> array we get from the toArray is always fresh and not escaping anywhere in 
> any well-behaved collection, so the clone could be elided. But if not then 
> both toArray and clone are intrinsified operations that are heavily optimized 
> and pretty fast even when interpreting, so emulating it with an external loop 
> might end up taking more time even at peak. While likely taking longer to 
> reach that peak. Using dumb, shared and common code (especially things that 
> get JITted early anyhow) is nice in areas that see most action during 
> startup/warmup.

Ok, please keep it the way it is in your current patch then.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-03 Thread Claes Redestad
On Fri, 3 Jun 2022 15:06:48 GMT, Jorn Vernee  wrote:

>> Claes Redestad has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Review comments, eagerly convert sooner in tryFinally
>
> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5269:
> 
>> 5267: }
>> 5268: 
>> 5269: static MethodHandle dropArguments(MethodHandle target, int pos, 
>> Class[] valueTypes, boolean trusted) {
> 
> Having a boolean that flips the behaviour makes it harder to know what that 
> `true` or `false` literal at the call site does. I'd suggest splitting this 
> into `dropArgumentsTrusted`, which doesn't clone the array, and 
> `dropArguments` which always makes a copy (and the latter calls former). WDYT?

Yeah, that sounds better.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-03 Thread Claes Redestad
On Fri, 3 Jun 2022 15:18:52 GMT, Jorn Vernee  wrote:

>> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5266:
>> 
>>> 5264:  */
>>> 5265: public static MethodHandle dropArguments(MethodHandle target, int 
>>> pos, List> valueTypes) {
>>> 5266: return dropArguments(target, pos, valueTypes.toArray(new 
>>> Class[0]), false);
>> 
>> A bit unfortunate that we can't trust this `toArray` to do a copy. I was 
>> going to suggest Stream, but it has the same issue (someone might have a 
>> custom stream implementation).
>> 
>> I do think a manual copy of the array is possible by having a loop though:
>> Suggestion:
>> 
>> Class[] ptypes = new Class[valueTypes.size()];
>> for (int i = 0; i < ptypes.length; i++) {
>> ptypes[i] = valueTypes.get(i);
>> }
>> return dropArguments(target, pos, ptypes, false);
>> 
>> 
>> (or, maybe extract such a loop to a helper method for clarity).
>
> The same could be done for the public `dropArgumentsToMatch` I think.

I'm not so sure. 

First of all we're no worse than before with the defensive copying here. Second 
of an optimizing compiler might theoretically be able to see that the array we 
get from the toArray is always fresh and not escaping anywhere in any 
well-behaved collection, so the clone could be elided. But if not then both 
toArray and clone are intrinsified operations that are heavily optimized and 
pretty fast even when interpreting, so emulating it with an external loop might 
end up taking more time even at peak. While likely taking longer to reach that 
peak. Using dumb, shared and common code (especially things that get JITted 
early anyhow) is nice in areas that see most action during startup/warmup.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-03 Thread Jorn Vernee
On Fri, 3 Jun 2022 15:09:24 GMT, Jorn Vernee  wrote:

>> Claes Redestad has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Review comments, eagerly convert sooner in tryFinally
>
> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5266:
> 
>> 5264:  */
>> 5265: public static MethodHandle dropArguments(MethodHandle target, int 
>> pos, List> valueTypes) {
>> 5266: return dropArguments(target, pos, valueTypes.toArray(new 
>> Class[0]), false);
> 
> A bit unfortunate that we can't trust this `toArray` to do a copy. I was 
> going to suggest Stream, but it has the same issue (someone might have a 
> custom stream implementation).
> 
> I do think a manual copy of the array is possible by having a loop though:
> Suggestion:
> 
> Class[] ptypes = new Class[valueTypes.size()];
> for (int i = 0; i < ptypes.length; i++) {
> ptypes[i] = valueTypes.get(i);
> }
> return dropArguments(target, pos, ptypes, false);
> 
> 
> (or, maybe extract such a loop to a helper method for clarity).

The same could be done for the public `dropArgumentsToMatch` I think.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-03 Thread Jorn Vernee
On Fri, 27 May 2022 19:52:30 GMT, Claes Redestad  wrote:

>> In preparation of #8855 this PR refactors the conversions from `List` to 
>> array and array to `List`, reducing the number of conversions when calling 
>> `MethodHandles.dropArguments` in particular. This remove about ~5% of 
>> allocations on the `StringConcatFactoryBootstraps` microbenchmark.
>
> Claes Redestad has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Review comments, eagerly convert sooner in tryFinally

src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5266:

> 5264:  */
> 5265: public static MethodHandle dropArguments(MethodHandle target, int 
> pos, List> valueTypes) {
> 5266: return dropArguments(target, pos, valueTypes.toArray(new 
> Class[0]), false);

A bit unfortunate that we can't trust this `toArray` to do a copy. I was going 
to suggest Stream, but it has the same issue (someone might have a custom 
stream implementation).

I do think a manual copy of the array is possible by having a loop though:
Suggestion:

Class[] ptypes = new Class[valueTypes.size()];
for (int i = 0; i < ptypes.length; i++) {
ptypes[i] = valueTypes.get(i);
}
return dropArguments(target, pos, ptypes, false);


(or, maybe extract such a loop to a helper method for clarity).

src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5269:

> 5267: }
> 5268: 
> 5269: static MethodHandle dropArguments(MethodHandle target, int pos, 
> Class[] valueTypes, boolean trusted) {

Having a boolean that flips the behaviour makes it harder to know what that 
`true` or `false` literal at the call site does. I'd suggest splitting this 
into `dropArgumentsTrusted`, which doesn't clone the array, and `dropArguments` 
which always makes a copy (and the latter calls former). WDYT?

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-02 Thread liach
On Thu, 2 Jun 2022 15:19:44 GMT, Сергей Цыпанов  wrote:

>> The clone is needed - as the `List>` may be a custom implementation 
>> of List - so you cannot make any assumption on the concrete implementation 
>> of `toArray`.
>
> But we can make an assumption on the behavior of particular method and the 
> JavaDoc is clear about it. If a user passes an incorrect implementation of 
> the `List` interface then it's their own responsibility.

We can't rule out malicious code holding the array reference it returns in 
toArray and updates that array to cause damage.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-02 Thread Сергей Цыпанов
On Thu, 2 Jun 2022 14:25:55 GMT, Daniel Fuchs  wrote:

>> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5462:
>> 
>>> 5460: Objects.requireNonNull(target);
>>> 5461: Objects.requireNonNull(newTypes);
>>> 5462: return dropArgumentsToMatch(target, skip, 
>>> newTypes.toArray(new Class[0]).clone(), pos, false);
>> 
>> Do we really need to clone an array returned from `List.toArray()`? As far 
>> as I know from the JavaDoc of `List` if the passed array is not long enough 
>> to include all the items then the new array must be allocated. Here we 
>> always pass empty arrays, so the new ones are returned from `toArray()` 
>> method and we don't need `clone()`, right?
>
> The clone is needed - as the `List>` may be a custom implementation 
> of List - so you cannot make any assumption on the concrete implementation of 
> `toArray`.

But we can make an assumption on the behavior of particular method and the 
JavaDoc is clear about it. If a user passes an incorrect implementation of the 
`List` interface then it's their own responsibility.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-02 Thread Daniel Fuchs
On Thu, 2 Jun 2022 13:59:50 GMT, Сергей Цыпанов  wrote:

>> Claes Redestad has updated the pull request incrementally with one 
>> additional commit since the last revision:
>> 
>>   Review comments, eagerly convert sooner in tryFinally
>
> src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5462:
> 
>> 5460: Objects.requireNonNull(target);
>> 5461: Objects.requireNonNull(newTypes);
>> 5462: return dropArgumentsToMatch(target, skip, newTypes.toArray(new 
>> Class[0]).clone(), pos, false);
> 
> Do we really need to clone an array returned from `List.toArray()`? As far as 
> I know from the JavaDoc of `List` if the passed array is not long enough to 
> include all the items then the new array must be allocated. Here we always 
> pass empty arrays, so the new ones are returned from `toArray()` method and 
> we don't need `clone()`, right?

The clone is needed - as the `List>` may be a custom implementation of 
List - so you cannot make any assumption on the concrete implementation of 
`toArray`.

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-06-02 Thread Сергей Цыпанов
On Fri, 27 May 2022 19:52:30 GMT, Claes Redestad  wrote:

>> In preparation of #8855 this PR refactors the conversions from `List` to 
>> array and array to `List`, reducing the number of conversions when calling 
>> `MethodHandles.dropArguments` in particular. This remove about ~5% of 
>> allocations on the `StringConcatFactoryBootstraps` microbenchmark.
>
> Claes Redestad has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Review comments, eagerly convert sooner in tryFinally

src/java.base/share/classes/java/lang/invoke/MethodHandles.java line 5462:

> 5460: Objects.requireNonNull(target);
> 5461: Objects.requireNonNull(newTypes);
> 5462: return dropArgumentsToMatch(target, skip, newTypes.toArray(new 
> Class[0]).clone(), pos, false);

Do we really need to clone an array returned from `List.toArray()`? As far as I 
know from the JavaDoc of `List` if the passed array is not long enough to 
include all the items then the new array must be allocated. Here we always pass 
empty arrays, so the new ones are returned from `toArray()` method and we don't 
need `clone()`, right?

-

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


Re: RFR: 8287442: Reduce list to array conversions in java.lang.invoke.MethodHandles [v2]

2022-05-27 Thread Claes Redestad
> In preparation of #8855 this PR refactors the conversions from `List` to 
> array and array to `List`, reducing the number of conversions when calling 
> `MethodHandles.dropArguments` in particular. This remove about ~5% of 
> allocations on the `StringConcatFactoryBootstraps` microbenchmark.

Claes Redestad has updated the pull request incrementally with one additional 
commit since the last revision:

  Review comments, eagerly convert sooner in tryFinally

-

Changes:
  - all: https://git.openjdk.java.net/jdk/pull/8923/files
  - new: https://git.openjdk.java.net/jdk/pull/8923/files/019e2ef8..15ff2125

Webrevs:
 - full: https://webrevs.openjdk.java.net/?repo=jdk=8923=01
 - incr: https://webrevs.openjdk.java.net/?repo=jdk=8923=00-01

  Stats: 4 lines in 2 files changed: 0 ins; 0 del; 4 mod
  Patch: https://git.openjdk.java.net/jdk/pull/8923.diff
  Fetch: git fetch https://git.openjdk.java.net/jdk pull/8923/head:pull/8923

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