On Feb 21, 2014, at 12:52 AM, Doug Lea <d...@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.hol...@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.