Hello,

So I have joined this list many years later than the cool kids, because
I have been reading the API docs and considering using SwitchPoint in a
design, and I wanted to be sure I understand its properties before blowing
too much time on it.

The questions I still had after the javadocs sent me on to the OpenJDK
GitHub repo to look at the sources, where I saw that SwitchPoint uses
MutableCallSite (as indeed its javadoc says "Simple implementations ...
may"), so invalidateAll relies on MutableCallSite.syncAll for the magic
to happen, and MutableCallSite.syncAll is ... interesting.

It has a very long javadoc comment that begins by appearing to make some
attractive promises:

1. effect is to force all future readers of each call site's target
   to accept the most recently stored value
2. may (may??) block until all readers have (somehow) decached all
   previous versions
3. reader threads may observe previous versions of the target
   until the syncAll call returns. (Does this mean they may not do so
   after the syncAll call returns? And if so, wouldn't that imply #2 is
   really something stronger than "may"?)
4. it "is likely to be expensive" (as the trade-off for having getTarget
   be as cheap as a plain read, and relying on magic to make the sync
   work).

But the javadoc for syncAll doesn't end there; it forges ahead into
Java Memory Model details, where the attractive early promises seem to get
renegotiated a bit. In particular, the very first thing it says about
"an arbitrary thread T (other than the current thread)" now starts
with an "if":

  "If T executes a synchronization action A after the volatile write"
  ... *then* it must see the updated target.

... the promise now begins to seem ... a bit ... conditional.

And indeed, the code of syncAll begins with the volatile write to
STORE_BARRIER (really a lazySet, which these days is documented as
the memory effects of setRelease). Then it calls getClass() on all
of the call sites, perhaps only to generate the specified NPE for
any null value, unless getClass() has some other effect I don't
know about.

And then after that loop, there seems to be the line with all the magic:

    // FIXME: NYI

And that's all there is to the method. And I see that's the magic line
in jdk17 [1] and all the way back to its appearance in jdk7 [2].

I see that I am not the first to notice that, and that the syncAll
method has been commented out in Android with a note that it wasn't
implemented. [3] (Which seems like it would break SwitchPoint, but then
it looks like Android never imported SwitchPoint at all.)

So by this point I am quite puzzled. I have spent the morning reviewing
the archives of this list, back to the inception of MutableCallSite
in late 2010. I read the initial design description by John Rose [4].
I see considerable discussion of using SwitchPoint, not least in the many
JRuby posts by Charles Oliver Nutter. Presumably if SwitchPoint didn't
reliably switch stuff, that would have been remarked on by now.

So what am I missing? Has this emperor got clothes I'm just not seeing?

Is part of the promised behavior actually being supplied by the VM
or compiler, maybe by treating this class specially, in a way I do
not see in the source?

Is the key to simply assume that every other thread T someday "executes
a synchronization action A" for unrelated reasons, and then sees the
update? If so, is there some upper bound that can be stated for how long
after syncAll returns that might be?

Were the Android developers correct in removing syncAll for being
unimplemented? Perhaps because it requires magical support from the VM
that is not present in their VM? Or were they just trigger-happy, removing
it only because they looked at the source and (like me) failed to convince
themselves nothing was missing?

If really nothing is missing, would it be worthwhile to remove
the // FIXME: NYI in the source, just for the peace of mind of people
(like me) who might be looking there to understand the behavior?

Thanks for any light you can open my eyes to ....

Regards,
Chapman Flack


[1]
https://github.com/openjdk/jdk17u/blob/master/src/java.base/share/classes/java/lang/invoke/MutableCallSite.java#L281
[2]
https://github.com/openjdk/jdk7/blob/34cd7bc/jdk/src/share/classes/java/dyn/MutableCallSite.java#L203
[3]
https://android.googlesource.com/platform/libcore/+/17162a1%5E!/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
[4] https://groups.google.com/g/jvm-languages/c/nJ0-hPx0VnY
_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to