Of Cycle Collection Optimizations
Of Cycle Collection Optimizations
-
Performance optimizations to reduce collection times
- Forget Skippable
- Black Bit Propagation
- Content Blaster
- Leak Fixes
-
Other optimizations
- Lazy purple buffer cleanup
- Snow white
-
Cycle collector is interested in possible garbage objects, not all the objects.
-
To reduce the number of objects in the cycle collection graph
remove certainly alive objects from it.
- Cycle collectable class may implement skippability (NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS*) to support
CanSkip* phases...
- CanSkip
- Run usually before graph creation has started
- May remove any object from the purple buffer -> the object will not be traversed during the next cycle collection
- CanSkipInCC
- Called when the cycle collection graph is about to be created.
- CanSkipThis
- Called during traversing
- Changing the state of any objects is not allowed.
- Cycle collector cares only about gray marked GC things
- If a cycle collectable object holds GC things and the object itself is know to be alive,
the gray bit can be removed from those GC things.
-
This gray bit removal, aka black bit propagation, happens implicitly
whenever a GC thing is used, or explicitly during ForgetSkippable/CanSkip.
- Specific optimization for DOM trees
- During CanSkip it is fast to detect DOM subtrees which are kept alive only by references in the subtree itself.
- Normal unlink during cycle collection kills external references, which leads to similar disconnected subtrees.
- To unbind nodes in this kind of DOM subtree can be done asynchronously and without cycle collector's unlink by using
ContentUnbinder, aka Content Blaster.
- Leaks may increase the number of objects in the graph.
- ...so fixing such bugs is good for responsiveness.
- There has been all kinds of leaks:
- Browser chrome or addons keeping content objects alive. (hueyfix)
- Random C++ implemented objects keeping DOM objects alive, for example nsFind, Necko, WebRTC...
- Bad scheduling of CC or GC (only a very temporary "leak")
Lazy purple buffer cleanup
-
Decreasing the reference count of a cycle collectable object makes it a possible garbage object.
- Originally Release call of a cycle collectable object put the
object to the purple buffer and AddRef call removed it from there.
- Since forget skippable goes anyway through the whole purple buffer relatively often,
it was possible to simplify AddRef so that it just flagged the object to be non-purple and purple buffer cleanup happened
during forget skippable or cycle collection.
- Originally refcnt member variable in the cycle collectable objects
was either a counter or pointer to a purple buffer entry, which had the actual reference count.
-
Whenever there was a purple buffer entry, increasing or decreasing reference count required
accessing also the purple buffer entry.
-
In the new setup refcnt is a counter + flags, and purple buffer itself keeps pointer to the refcnt and to its owner object
-
In this setup cycle collector deletes the objects.
Dropping reference count to zero just marks the object to be snow white.