RFR: 8302822: Method/Field/Constructor/RecordComponent::getGenericInfo() is not thread safe
Jaikiran Pai
jpai at openjdk.org
Mon Feb 20 08:30:25 UTC 2023
On Sun, 19 Feb 2023 18:41:18 GMT, liach <duke at openjdk.org> wrote:
> 8302822: Method/Field/Constructor/RecordComponent::getGenericInfo() is not thread safe
Hello @liach, I don't follow what this change is achieving. I think I might be missing something though. I read through the linked JIRA which states:
> In the getGenericInfo() methods of Method, Field, Constructor, and RecordComponent, the genericInfo field is read twice, and the second read returned may be null under race conditions.
Considering the `Constructor` class as an example, which looks like this:
@Override
ConstructorRepository getGenericInfo() {
// lazily initialize repository if necessary
if (genericInfo == null) {
// create and cache generic info repository
genericInfo =
ConstructorRepository.make(getSignature(),
getFactory());
}
return genericInfo; //return cached repository
}
I can understand that the `ConstructorRepository.make(getSignature(), getFactory());` might end up getting called more than once in case of race (or if ConstructorRepository.make(getSignature(), getFactory()) really returns null), but those should be harmless races. Plus, the getSignature() isn't expensive, since it returns an already assigned `final` field.
Is there some other race condition here?
The JBS issue also states:
> Class::getGenericInfo() originally had the same issue, but was fixed in 8016236.
I had a look at the RFR https://mail.openjdk.org/pipermail/core-libs-dev/2013-June/017798.html. That's a slightly different issue, from what I understand. In that case, the call to getGenericInfo() was being preceded by a call to some other expensive method. The change there proposed to first call getGenericInfo() and let it be initialized and only then decide whether to call the other expensive methods.
In that change, I can see that the `getGenericInfo()` method on the `Class` class was changed too and that change is almost similar to what's being proposed in this current PR. However, `Class.genericInfo` field is `volatile` and I think that's why Doug changed that method to first write it to a local field and then use that local field for the rest of the work. In the current PR however, which touches `Field`, `Method`, `Constructor` and `RecordComponent`, the `genericInfo` isn't a `volatile` field in any of those classes, so I don't see why this local assignment is needed or would help. Am I missing something?
-------------
PR: https://git.openjdk.org/jdk/pull/12643
More information about the core-libs-dev
mailing list