Confirmed users
162
edits
m (→Lifecycle and refcounts: typo) |
|||
| Line 36: | Line 36: | ||
# The reference the <tt>JSObject</tt>'s private slot has to the <tt>XPCWrappedNative</tt>. | # The reference the <tt>JSObject</tt>'s private slot has to the <tt>XPCWrappedNative</tt>. | ||
This models a simple fact: for the <tt>XPCWrappedNative</tt> to die, both the C++ XPCOM world ''and'' the JS heap ought to have | This models a simple fact: for the <tt>XPCWrappedNative</tt> to die, both the C++ XPCOM world ''and'' the JS heap ought to have forgotten about it. If either side still sees it, it should stay alive. | ||
Thus the <tt>JSObject</tt> keeps the <tt>XPCWrappedNative</tt> alive, and the <tt>XPCWrappedNative</tt> keeps the <tt>nsISupports</tt> that it's pointing to alive. But there's an important detail: the <tt>XPCWrappedNative</tt> does ''not'' directly keep the <tt>JSObject</tt> alive. Doing so unconditionally -- for example rooting the <tt>JSObject</tt> -- would give rise to a cyclic graph: the pair of objects would keep each other alive indefinitely. So the <tt>XPCWrappedNative</tt> holds a pointer to the <tt>JSObject</tt>, but doesn't root it. | Thus the <tt>JSObject</tt> keeps the <tt>XPCWrappedNative</tt> alive, and the <tt>XPCWrappedNative</tt> keeps the <tt>nsISupports</tt> that it's pointing to alive. But there's an important detail: the <tt>XPCWrappedNative</tt> does ''not'' directly keep the <tt>JSObject</tt> alive. Doing so unconditionally -- for example rooting the <tt>JSObject</tt> -- would give rise to a cyclic graph: the pair of objects would keep each other alive indefinitely. So the <tt>XPCWrappedNative</tt> holds a pointer to the <tt>JSObject</tt>, but doesn't root it. | ||