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

Forget Skippable

  • 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.

Black Bit Propagation

  • 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.

Content Blaster

  • 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.

Leak Fixes

  • 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.

Snow white

  • 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.