Hi,

On 07/14/2017 04:22 PM, Aleksey Shipilev wrote:
On 07/14/2017 04:12 PM, Claes Redestad wrote:
Thing is, "volatile" is not as strong as "final" for racy initializations:

https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-volatiles-are-finals


If that is not a concern -- e.g. if private constructor is never used to make
shared OSFs -- then "volatile" is superfluous. If it is a concern, then
"volatile" is not enough, and you have to keep "final".
Gosh!

Seeing how it's possible to lookup ObjectStreamClass and get at
ObjectStreamField's that might have been created from the internal
constructors, I think it *is* a concern.

Thus the only viable option that allows us to be correct *and* lazy might be to
add a new field that is lazily initialized only when using the public 
constructors:

http://cr.openjdk.java.net/~redestad/8184603/jdk.02/
I think this is fine from concurrency standpoint. Not sure how safe it is to
increase OSF footprint, that's your call! I also think the largest improvement
would be from avoiding the intern() call in constructor -- I frequently observed
it on the OSF hot paths. I would trade excess field for avoiding String.intern()
any day.

It seems that interning signature(s) is important for correctness (for example, in ObjectOutputStream.writeTypeString(str) the 'str' is used to lookup a handle so that handles are put into stream instead of the type signature(s) for multiple references to the same type). Looking up objects in handles table is based on identity comparison.

But there might be a way to obtain a singleton signature String per type and still profit. By adding a field to java.lang.Class and caching the JVM signature there. This would also be a useful public method, don't you think?

Out of 191 ObjectStreamField constructions I found in JDK sources, there are only 39 distinct field types involved, so the number if intern() calls is reduced by a factor of ~5. There's no need to cache signature in ObjectStreamField(s) this way any more, but there must still be a single final field for ObjectStreamField(s) constructed with explicit signature(s).

Here's how this looks like in code:

http://cr.openjdk.java.net/~plevart/misc/Class.getJvmTypeSignature/webrev.01/


What do you think?

Regards, Peter


As Doug Lea mentions offlist, another alternative would be to do fullFence at
the end of OSF private constructor. But, this is low-level, and relies on
hardware that handles data-dependent loads fine on reader side (which is true
for all arches OpenJDK targets, I think). If there is no pressing need to keep
OSF footprint minimal, I'd avoid doing explicit fences.

Thanks,
-Aleksey


Reply via email to