[sgen] Fix hazard pointer free deadlock problem. Fixes #9828.
The hazard pointer code, which assists in lock free algorithms, tries
to free some data it had to keep around (because other threads were
still using it) whenever it is invoked. Obviously, the code that frees
data must never lock, or else the code that uses hazard pointers might
lock, as well.
The JIT info table pointer code uses malloc/free to allocate its memory,
so its free function uses free(), which might lock. Even worse, it takes
the domain lock. (The JIT info table is lock-free for readers, not for writers,
which explains why it uses hazard pointers.)
To solve the problem we separate hazard pointers into those whose free
functions might lock, and those who will not, and we provide the information
on whether we're currently in a context where locking is permissible. If it isn't,
no free function which might lock must be called. To make sure they are
called eventually we try to free a few after restarting the world in SGen, at
which point locking is allowed.