On Wed, 22 Mar 2023 23:01:32 GMT, Chen Liang <li...@openjdk.org> wrote:
> This change exposes the CLOSED array Otherwise we have to either call `getInIfOpen()`/`getBufIfOpen` making them at least protected or dodge this somehow via `SharedSecrets` > I mean that additional API exposure is acceptable and backward compatible, > but the previous contract to subclasses that the protected `buf` is > initialized after superclass constructor execution breaks. Before this change > proceeds, we have to check how many subclasses of `BufferedInputStream` > access this `buf` in a wide range of libraries and evaluate the impact, which > I anticipate to be huge. > > A slightly less impactful approach would be sharing a `byte[0]` for a newly > initialized state, like in ArrayList, so users anticipating a closed > `BufferedInputStream` to have a null `buf` will still work. But users > anticipating a usable buf after constructor will still break: for instance, > since `getBufIfOpen` is private but the `buf` field it uses is protected, > nothing prevents subclasses from copying the same implementation over; and > the same implementation will stop working with this new optimization. @liach with your approach tests are green > src/java.base/share/classes/java/io/BufferedInputStream.java line 78: > >> 76: private final InternalLock lock; >> 77: >> 78: /** > > These should be reverted, now that the subclasses will see the same behavior > as before. But it's just comment clean up > src/java.base/share/classes/java/io/BufferedInputStream.java line 211: > >> 209: throw new IllegalArgumentException("Buffer size <= 0"); >> 210: } >> 211: buf = new byte[0]; > > Two recommendations: > 1. This `new byte[0]` can be safely shared, so I recommend you to put it in a > static final field to avoid reallocation > 2. The subclass compatibility can be retained by: > Suggestion: > > buf = (getClass() == BufferedInputStream.class) ? new byte[0] : new > byte[size]; Good point, done! > src/java.base/share/classes/java/io/BufferedInputStream.java line 216: > >> 214: throw new IllegalArgumentException("Buffer size <= 0"); >> 215: } >> 216: buf = getClass() == BufferedInputStream.class ? EMPTY : new >> byte[size]; > > Actually, you can merge this `getClass()` check with the one below for locks. Done ------------- PR Comment: https://git.openjdk.org/jdk/pull/13150#issuecomment-1480701591 PR Comment: https://git.openjdk.org/jdk/pull/13150#issuecomment-1481236336 PR Review Comment: https://git.openjdk.org/jdk/pull/13150#discussion_r1146316757 PR Review Comment: https://git.openjdk.org/jdk/pull/13150#discussion_r1146321335 PR Review Comment: https://git.openjdk.org/jdk/pull/13150#discussion_r1146414668