RFR: 8324646: Avoid Class.forName in SecureRandom constructor
Aleksey Shipilev
shade at openjdk.org
Wed Jan 24 17:50:31 UTC 2024
On Wed, 24 Jan 2024 15:25:28 GMT, Oli Gillespie <ogillespie at openjdk.org> wrote:
> Avoid expensive `Class.forName` call when constructing Providers such as `SecureRandom` which take constructor parameters. This can easily be cached in EngineDescription (this cache already existed before, it was removed in [JDK-8280970](https://bugs.openjdk.org/browse/JDK-8280970) as unused, I'm bringing it back unchanged to support this new usage).
>
> Benchmark results on my Linux x86 host show around a 20% reduction in time to create a new `SecureRandom` instance. Most of the remaining overhead is due to a failing constructor lookup - see [JDK-8324648](https://bugs.openjdk.org/browse/JDK-8324648).
>
>
> Before
> newSecureRandom avgt 2930 ± 50 ns/op
>
> After
> newSecureRandom avgt 2400 ± 33 ns/op
>
>
> I have seen multiple real-world applications which call `new SecureRandom()` on the hot path, so I believe efficiency here is important.
This looks promising to me! But we need to polish this a bit:
src/java.base/share/classes/java/security/Provider.java line 1560:
> 1558: final boolean supportsParameter;
> 1559: final String constructorParameterClassName;
> 1560: private volatile Class<?> constructorParameterClass;
Style: no need for `private` here, match what other fields are doing.
src/java.base/share/classes/java/security/Provider.java line 1568:
> 1566: }
> 1567:
> 1568: Class<?> getConstructorParameterClass() throws ClassNotFoundException {
I think we want to do what `Service.getImplClass` is doing, for extra safety: retain cached class on a `WeakReference`. This would avoid accidental class leakage in this code.
src/java.base/share/classes/java/security/Provider.java line 1909:
> 1907: } else {
> 1908: ctrParamClz = cap.constructorParameterClassName == null?
> 1909: null : cap.getConstructorParameterClass();
Maybe we should move the ternary for `cap.constructorParameterClassName == null` into new method to begin with.
test/micro/org/openjdk/bench/java/security/SecureRandomBench.java line 1:
> 1: package org.openjdk.bench.java.security;
No copyright header?
test/micro/org/openjdk/bench/java/security/SecureRandomBench.java line 16:
> 14:
> 15: @Benchmark
> 16: public SecureRandom newSecureRandom() throws Exception {
Just "create()", I think. No need to repeat it with `SecureRandomBench.newSecureRandom`.
-------------
PR Review: https://git.openjdk.org/jdk/pull/17559#pullrequestreview-1842025562
PR Review Comment: https://git.openjdk.org/jdk/pull/17559#discussion_r1465331538
PR Review Comment: https://git.openjdk.org/jdk/pull/17559#discussion_r1465330794
PR Review Comment: https://git.openjdk.org/jdk/pull/17559#discussion_r1465332784
PR Review Comment: https://git.openjdk.org/jdk/pull/17559#discussion_r1465332949
PR Review Comment: https://git.openjdk.org/jdk/pull/17559#discussion_r1465334379
More information about the security-dev
mailing list