SI-8131 fixes residual race condition in runtime reflection

Apparently some completers can call setInfo while they’re not yet done,
which resets the LOCKED flag, and makes anything that uses LOCKED to
track completion unreliable. Unfortunately, that’s exactly the mechanism
that was used by runtime reflection to elide locking for symbols that are
known to be initialized.

This commit fixes the problematic lock elision strategy by introducing
an explicit communication channel between SynchronizedSymbol’s and their
completers. Now instead of trying hard to infer whether it’s already
initialized or not, every symbol gets a volatile field that can be queried
to provide necessary information.
ensures that runtime reflection symbols are thread-safe

A long time ago, when implementing the first version of reflection sync,
we discovered that, even though we had the SynchronizedSymbol trait that
covered critical methods of Symbol with locks, there were no symbols to
benefit from that, because everyone’s transitively created by root and
root itself wasn’t synchronized :)

It looks like being all euphoric over discovering and fixing such a
ridiculous bug, we’ve missed some of the symbols which remained unsynced,
e.g. NothingClass. This commit fixes this oversight and enforces the policy
in an assertion that now lives in Symbol’s base constructor.