[13] RFR JDK-7107615 "scalability bloker in javax.crypto.JceSecurity"

Valerie Peng valerie.peng at oracle.com
Fri May 10 23:36:41 UTC 2019


Hi Xuelei,

Based on our earlier discussions, I experimented with a few approaches 
and updated the changes accordingly:

http://cr.openjdk.java.net/~valeriep/7107615/webrev.02/

Please let me know if you have more comments.

Thanks,
Valerie
On 4/19/2019 3:58 PM, Valerie Peng wrote:
> Ok, thanks for the double checking suggestion.
>
> Given the somewhat limited number of providers, I am exploring other 
> data structures such as WeakHashMap.
>
> Will have to put this on hold during my upcoming week-long vacation 
> and resume on 4/29.
>
> Thanks!
> Valerie
> On 4/16/2019 3:43 PM, Xuelei Fan wrote:
>> On 4/16/2019 2:16 PM, Valerie Peng wrote:
>>> Hi Xuelei,
>>>
>>> Thanks for the comments.
>>>
>>> On 4/16/2019 8:58 AM, Xuelei Fan wrote:
>>>> 213-217:
>>>> Previously, the set/get of both verificationResults and 
>>>> verifyingProviders are synchronized.  With this update, the get of 
>>>> verificationResults is not out of the set synchronized block, so 
>>>> there is a competition introduced.  I think it would be nice to 
>>>> double check the verificationResults in the synchronized block.
>>>>   synchronized (JceSecurity.class) {
>>>> +     //  double check if the provider has been verified
>>>>       ...
>>>>   }
>>>>
>>> Hmm, are you talking about the verificationResults.get(pKey) call 
>>> (line 206) and move it inside the block of synchronized 
>>> (JceSecurity.class) (line 212)?
>> I meant to get/check twice.
>> ... getVerificationResult(Provider p) {
>>     ...
>> // get/check block
>>     Object o = verificationResults.get(pKey);
>>     if ( o == ...) {
>>         ...
>>     } else if (o != null) {
>>         ...
>>     }
>>
>>     synchronized (JceSecurity.class) {
>>        // double check if the provider has been verified.
>> // use the get/check block again
>>        Object o = verificationResults.get(pKey);
>>        if ( o == ...) {
>>            ...
>>        } else if (o != null) {
>>            ...
>>        }
>>
>>        // further operation is the provider has not been verified.
>>        ....
>>     }
>> }
>>
>>> If that's what you suggest, I think that'd take away the key idea of 
>>> this performance rfe fix. My understanding of the patch is to use a 
>>> ConcurrentHashMap for "verificationResult" so accesses to this 
>>> "verificationResult" cache are controlled by the finer-grained model 
>>> of ConcurrentHashMap. On the other hand, verifyingProviders map and 
>>> the time consuming/potentially complex verifyProvider(...) call are 
>>> still inside the synchronized (JceSecurity.class) block. Maybe it'd 
>>> be clearer if I had re-written the code and move the 
>>> verificationResults.put(...) calls outside of the synchronized 
>>> (JceSecurity.class) block. The way I look at it, this change 
>>> separates out the "verificationResult" cache from the rest of the 
>>> provider verification logic and uses ConcurrentHashMap instead of 
>>> JceSecurity.class in order to improve performance.
>>>
>> I think there is a competition.  If two threads try to get the lock, 
>> line 212-227 get executed in both thread.  The double checking scheme 
>> could avoid it as when the 2nd thread get the lock, it will use the 
>> result of the 1st thread.
>>
>>>> I did not get the idea to use verifyingProviders.  In line 219, a 
>>>> provider was inserted into the map, and in the final block, line 
>>>> 235, the provider was removed from the map.  There is no other 
>>>> update of the map, so the map should always be empty and not really 
>>>> used. Am I missing something?  Could the verifyingProviders field 
>>>> get removed?
>>>>
>>> The verifyingProviders field is for detecting potential recursions 
>>> during the provider verification. the verifyProvider(URL, Provider) 
>>> call will call ProviderVerifier.verify(). This will trigger provider 
>>> jar file verification. Depending on runtime provider verification, 
>>> this may trigger another provider being loaded/verified. As 
>>> getVerificationResult(Provider) is being called by the pkg private 
>>> static method JceSecurity.getInstance(...) which is used internally 
>>> by other JCA classes, it's possible for getVerificationResult(...) 
>>> to be recursively called and thus the verifyingProviders field will 
>>> help detect if somehow verifying the current provider will require 
>>> loading another JCA service from the current provider.
>>>
>> I see the point now.  Thanks!
>>
>>>>
>>>> 406-426:
>>>> I may add a blank line between two different blocks (methods, field 
>>>> and methods).
>>>>
>>> Sure, added.
>>>
>>>
>>>> - 416 if (o instanceof IdentityWrapper == false) {
>>>> + 416  if (!(o instanceof IdentityWrapper)) {
>>>>
>>>> I prefer to use "!" operator.
>>>
>>> Sure.
>>>
>> Thanks!
>>
>> Xuelei
>>
>>> Webrev updated at: 
>>> http://cr.openjdk.java.net/~valeriep/7107615/webrev.01/
>>>
>>> Thanks,
>>> Valerie
>>>>
>>>> Xuelei
>>>>
>>>> On 4/15/2019 6:20 PM, Valerie Peng wrote:
>>>>>
>>>>> Anyone has time to review this performance rfe? The fix is based 
>>>>> on Sergey's suggested patch.
>>>>>
>>>>> RFE: https://bugs.openjdk.java.net/browse/JDK-7107615
>>>>>
>>>>> Webrev: http://cr.openjdk.java.net/~valeriep/7107615/webrev.00/
>>>>>
>>>>> Mach5 run is clean.
>>>>>
>>>>> Thanks,
>>>>> Valerie



More information about the security-dev mailing list