JDK 9 RFR of JDK-8035279: Clean up internal deprecations in BigInteger

Paul Sandoz paul.sandoz at oracle.com
Fri Feb 21 09:06:38 UTC 2014


On Feb 21, 2014, at 12:52 AM, Doug Lea <dl at cs.oswego.edu> wrote:

> On 02/20/2014 05:11 PM, David Holmes wrote:
>> On 21/02/2014 7:20 AM, Paul Sandoz wrote:
>>> On Feb 20, 2014, at 9:09 PM, David Holmes <david.holmes at oracle.com> wrote:
>>>> In practice, because there are also final fields in these instances
>>>> implementations will most likely perform a storestore barrier after
>>>> construction and prior to setting the reference to the created object.
>>> 
>>> Yes, that is what i was banking on.
>>> 
>>> That is how hotspot behaves, right?
>> 
>> Yes.
>> 

I could not resist an little experiment:

    static class X {
        String a;
        final String f;
        String b;
        public X() { a = "A"; f = "S"; b = "B"; }
    }


067   B3: #     N79 <- B5 B2  Freq: 1
067     movl    [RAX + #12 (8-bit)], narrowoop: java/lang/String:exact *        # compressed ptr
06e     movl    [RAX + #16 (8-bit)], narrowoop: java/lang/String:exact *        # compressed ptr
075     movl    [RAX + #20 (8-bit)], narrowoop: java/lang/String:exact *        # compressed ptr
07c
07c     MEMBAR-storestore (empty encoding)
07c     # checkcastPP of RAX
07c     movq    R10, RAX        # ptr -> long
07f     shrq    R10, #9
083     movq    R11, 0x0000000192569000 # ptr
08d     movb    [R11 + R10], R12        # short/char (R12_heapbase==0)
091     MEMBAR-release ! (empty encoding)
091     addq    rsp, 16 # Destroy frame


That "storestore" is for the object header IIUC (which just so happens to be placed after all fields have been set) and the "release" is due to the final field, both of which are noops on x86.


>>> But, you are saying other VMs might not do so?
>> 
>> Right. A storestore at the end of construction is a simple and obvious way to
>> implement the final-field semantics, but there may be other ways. The visibility
>> guarantees for final fields extends only to those fields, and objects accessed
>> through them.
> 
> Which has turned out in practice to be the only plausible way to do
> this, so the spec might as well have said so.
> 

Yeah, i was wondering what VMs out there would do it differently.

It would be a shame to take the 3x volatile hit to cover less common environments. (Another recent issue related to initialization of volatiles on AbstractMap indicated some awkward interactions with G1.)

I think we should try and use zero, as John says (alas @Stable is package private to j.l.invoke), and replace 0 with another value such as MIN_VALUE if one is unsure of the bounds:

  int lsb;
  if ((lsb = lowestSetBit) == 0) {
    ...
    lowestSetBit = lsb != 0 ? lsb : Integer.MIN_VALUE;
  }
  return lsb != Integer.MIN_VALUE : lsb ? 0;


> Paul:  If you'd like to be pedantically correct at the
> expense of a lot more overhead, you could  use
> AtomicXFieldUpdater.lazySet in the constructor.

Role on "lowestSetBit.volatile..." !


> But since these changes are targeting JDK9, it is very
> likely that the memory model will be updated to
> confirm that the current approach is legal by the time
> it ships.
> 

Looking forward to that :-)

Paul.


More information about the core-libs-dev mailing list