Skip to content

WIP: Use Toggle Refs on Object Instances

Overview

This merge fixes the "cycle issue" with the currently proposed expando system. (explanation of the "cycle issue" below)

Commits

The first commit in this merge was the first attempt at using toggle references to resolve the "cycle issue" with the current branch. (should be removed before picking)

The second commit is the successful attempt to resolve the cycle issue with toggle references.

The first was unsuccessful because it attempted to add toggle references on the ExpandoHolder, not ObjectInstance. Because ObjectInstance always held a reference - the toggle references on ExpandoHolder were not triggered.

What is the cycle issue?

In our JavaScript engine, SpiderMonkey, garbage collection is a trace-based system. Every object "traces" it's references, allowing the garbage collector to identify objects which are no longer referenced and clean them up.

A "cycle" occurs when an object references itself or two objects reference each other.

this.me = this;
a.b = b;
b.a = a;

In these cases the garbage collector will only be able to collect this or a/b if no other code references them.

In the current expando system, the garbage collector can never break these cycles for GObject's because the objects are never isolated.

current-trace

This is the current trace of an expando and GObject. red denotes C-based references (counting), black denotes JavaScript based references (traces). Note that the JSContext always traces the ExpandoHolder which always traces Expando. Because JSContext is not cleaned up until we exit, this is essentially a permanent reference. This is done to prevent custom JS properties (expando properties) on GObjects from "disappearing" if they are passed into C code and no longer referenced from JavaScript code. The downside, is that it will keep reference cycles alive indefinitely and the objects which they reference.

Solution

To prevent this, we need to "toggle" the tracing behavior once it is passed into C code and no longer referenced by JavaScript.

To meet that condition, we use GObject's toggle_ref which notifies us when only one reference remains on a given ObjectInstance. If only one reference remains, we know only JavaScript references the object. In that case, we remove the trace from JSContext to prevent a permanent reference and allow SpiderMonkey to garbage collect as needed. Otherwise, we keep the permanent reference in place to keep the JS properties alive when no longer referenced from JavaScript.

The diagram below represents this system. green highlights the changes made, red is GObject references, and black is JavaScript traces.

proposed

Edited by Evan Welsh

Merge request reports