Project Fission/DocShell Tree Replace
- 1 Overview
- 2 Usages of nsIDocShellTreeItem
- 2.1 Traverse of Tree Structure Only
- 2.2 Existing valid uses
- 2.3 Deep Access of Document Data
- 3 Example bugs
This wiki page tracks the work required to audit and fix all usage of the `nsIDocShellTreeItem` structure in Gecko, to update it to accommodate Fission semantics.
A large part of the Fission workload involves usage of information contained in docshells, windows, and documents - via the nsIDocShellTreeItem interface: 
In pre-fission semantics, the nsIDocShellTreeItem establishes the tree of nested documents, each of which may come from a different security context (origin). As all content data relevant to a given page lives in the same process in pre-Fission Firefox, the entire tree for a given page would be in process memory. This tree is traversed directly by a lot of gecko code: .
In post-Fission semantics, this tree will no longer be completely in process for a given top-level document. Only contiguous fragments of the tree from the same origin are held in the same process:
a.com | +-------+-------+ | | b.com/1 a.com/foo | +---------+ | | b.com/2 b.com/3 | | a.com/bar
In pre-fission semantics, the prior tree would be entirely contained in a single process. Post-fission, this tree will be split across two processes, with three tree fragments across them:
1. A tree fragment (a.com -> a.com/foo) in process A 2. A tree fragment (b.com/1 -> (b.com/2 | b.com/3)) in process B 3. A singleton tree fragment (a.com/bar) in process A
The current usages of `nsIDocShellTreeItem` assume that DocShell trees are in-process. These usages need to be fixed, using various fission-related support infrastructure such as `BrowsingContext`s, `WindowContext`s, and `TabContext`s - or using IPC to remote processes where necessary.
The usage of nsIDocShellTreeItem can be broken down into a few major categories.
Usages of nsIDocShellTreeItem
The uses of nsIDocShellTreeItem are broadly categorized by the kind of use. The categories are:
1. simple - uses which can be fixed by porting the tree traversal directly to the BrowsingContext tree instead of the DocShell tree. 2. sync-state - uses which require moving some existing state within a process-internal structure (e.g. Document, DocShell, Window, etc.) and moving it into a cross-process replicated structure like BrowsingContext, TabContext, or WindowContext. 3. hard - uses that will require some form of IPC or architectural change to fix 4. rename - helper functions which need to be re-named to reflect their in-process-only semantics, and their uses audited. 5. validate - existing uses which are likely consistent with Fission requirements, but must be verified and closed. These may involve some small cosmetic changes to code.
Bugs in a given category are whiteboard-tagged `[rm-docshell-tree-item:CATEGORY]` where `CATEGORY` is replaced with the specific category for the bug.
More detailed explanations of the types of uses are given below.
Traverse of Tree Structure Only
These uses involve simply using the child and parent pointers within `nsIDocShellTreeItem` to determine certain properties of a document - such as whether it's a root document, or whether it is the child of a root, or whether it has the same type (content vs. chrome) as its parent, etc.
These traversals are typically trivial to fix and form a large proportion of the usage of this structure. The fix typically involves changing the offending code to use `BrowsingContext` traversals instead of the DocShell tree.
As `BrowsingContext` is a cross-process, replicated tree, it fulfills expectations of having the full tree for a document within the querying process.
Existing valid uses
Existing uses of nsIDocShellTreeItem may be valid even in post-fission semantics. For example, some uses of nsIDocShellTreeItem may retrieve a same-origin parent, or null if the parent is not same-origin.
In these cases, the post-Fission behaviour will be consistent with the program logic. I am not explicitly documenting these cases with bugs.
Deep Access of Document Data
Some 20% of uses of nsIDocShellTreeItem access information held within DocShells, Documents, or Windows that may belong to ancestors or children in the tree.
Fixing these uses depends on the kind of information being accessed. There are a few ways to break down the kinds of information accessed:
1. Existing state information that is not security sensitive
These are fields, or flags held in Document, Window, DocShell, or other process-segregated structures, accessed via nsIDocShellTreeItem, which are not sensitive.
Fixing these uses depends on how often the underlying data changes. If the data being accessed is infrequently updated, the state should be moved to BrowsingContext, WindowContext, or TabContext (as appropriate), and synchronized across processes.
If this state is updated too frequently for it to be cross-process synchronized effectively, other options such as IPC must be considered.
2. Synthesized state information that is not security sensitive
This is similar to the first case, except that the information being accessed is not a specific existing field, but instead a characteristic that is synthesized from a number of different pieces of data within the internal structures.
- TODO: Put example bug here (IsARIALive - scans documents in tree heirarchy for presence of accessibility flags)
In these cases, a reasonable approach is to create a field in BrowsingContext or another context structure, which dynamically caches the synthesized information. Once again, an understanding of how often that particular synthesized state would need to be updated is relevant for this determination.
3. Access to security-sensitive information or complex information
This class of uses relates to information which cannot easily be moved into BrowsingContext, TabContext or WindowContext. Sometimes this is because the information is security sensitive, and other time its because the query over DocShell/Document/Window is too complex to be represented as a simple synthesized state.
These bugs tend to be difficult. Fortunately, many of these bugs relate to ongoing deep component work - including SessionHistory work, DOM Core work, etc.
Below are two example bugs in the `simple` and `sync-state` category: