synchronizes symbols

Synchronization via decoration would be neat if it actually worked.
Unfortunately, root symbols never got decorated, therefore their children
also never got decorated and all the way down to the very turtles.

This commit fixes this sad issue by turning root symbols from objects
to lazy vals. Yes, this is going to induce a performance penalty, which
will hopefully not be high enough to invalidate this cornerstone of our
synchronization strategy.

Now when root symbols are lazy vals, they can be overridden in the runtime
reflexive universe and decorated with SynchronizedSymbol, which makes their
children sync and sound.
reflection no longer uses atPhase and friends

Mentioned methods mutate the global `atPhaseStack` variable, which can
easily lead to imbalances and, ultimately, to the empty stack error.

Luckily for us, there's only one dummy phase, SomePhase, which is used
by runtime reflection, so there is absolutely zero need to invoke atPhase
in non-compiler reflexive universes.
synchronizes PackageScope.negatives

We don't have to serialize access to this cache, but we ought to
make the cache safe for being accessed from multiple threads at once.
synchronizes runtimeMirror
synchronizes toolboxes

We don't guarantee thread-safety of the front end, but everything else
looks good now.
synchronizes symbol materializers

Since runtime reflection doesn't have a luxury of enumerating all classes
on the classpath, it has to materialize symbols for top-level definitions
(packages, classes, objects) on demand.

Someone asks us for a class named `foo.Bar`? Easy. Let's speculatively create
a package named `foo` and then look up `newTypeName("bar")` in its decls.
This lookup, implemented in `SymbolLoaders.PackageScope` tests the waters by
trying to to `Class.forName("foo.Bar")` and then creates a ClassSymbol upon
success (the whole story is a bit longer, but the rest is irrelevant here).

That's all neat, but these non-deterministic mutations of the global symbol
table give a lot of trouble in multi-threaded setting. One of the popular
reflection crashes happens when multiple threads happen to trigger symbol
materialization multiple times for the same symbol, making subsequent
reflective operations stumble upon outrageous stuff like overloaded packages.

Short of significantly changing SymbolLoaders I see no other way than just
to slap a global lock on materialization in runtime reflection.
cleans up initialization of runtime reflection

At first I just tried to remove syntheticCoreClasses from missingHook
and put them into the initializer of freshly created mirrors in order to
reduce the non-determinism in mutations of the global symbol table.

And then it didn't work, crashing on me claiming that AnyRef is missing.
Apparently we still need AnyRefClass in missingHook, just because it's
impossible to initialize (i.e. unpickle) ScalaPackageClass without it.

And then it still didn't work, whining about multiple overloaded defs
of some synthetic symbols. That was really tricky, but I figured it out
as well by initializing ScalaPackageClass first before forcing any
synthetic symbols (see the details in comments).
introducing GIL to Scala reflection

On a serious note, I feel really uncomfortable about having to juggle
this slew of locks. Despite that I can't immediately find a deadlock,
I'm 100% sure there is one hiding in the shadows. Hence, I'm abandoning
all runtime reflection locks in favor of a single per-universe one.
optimizes Scala reflection GIL

First of all, GIL should only apply to runtime reflection, because noone
is going to run toolboxes in multiple threads: a) that's impossible, b/c
the compiler isn't thread safe, b) ToolBox api prevents that.

Secondly, the only things in symbols which require synchronization are:
1) info/validTo (completers aren't thread-safe),
2) rawInfo and its dependencies (it shares a mutable field with info)
3) non-trivial caches like in typeAsMemberOfLock

If you think about it, other things like sourceModule or associatedFile
don't need synchronization, because they are either set up when a symbol
is created or cloned or when it's completed.

We can say that symbols can be in four possible states: 1) being created,
2) created, but not yet initialized, 3) initializing, 4) initialized.
single thread. #2 and #4 don't need synchronization either, because the
only mutation symbols in runtime reflection can undergo is init. #3 is
dangerous and needs protection.
removes the assertion in missingHook

In the current synchronization scheme multiple threads can enter the
missingHook trying to materialize a package, which hasn't been created.

That's fine, because makeScalaPackage, which creates and enters package
symbols is synchronized and checks whether the creation is necessary
before commencing. Therefore even if makeScalaPackage is called multiple
times in rapid succession, the calls will be serialized and all calls
except the first one won't do anything.
runtime reflection: death from thousand threads

not anymore