This patch adds an API for posting a Core::Event::Type to the thread
event queue without requiring a full Core::Event object.
We use this API to avoid heap allocations for every timer and notifier
activation event.
The DeferredInvocationContext only existed to satisfy the requirement
in ThreadEventQueue that each event has an EventReceiver. However,
deferred_invoke() was not even using the EventReceiver to call its
callback. Therefore, we don't need to allocate one for every deferred
invocation.
This also prevents WeakPtr::strong_ref() from racing and leaking the
context object when invoking a function across threads.
The inline capacity on ThreadEventQueue::Private::queued_events caused
us to reserve (and importantly, not initialize!) 2 KiB of stack memory
when entering ThreadEventQueue::process().
This was causing any leftover pointers to GC-allocated objects within
that memory range to keep those objects alive, even when all other
references were gone.