We're already using lvalue functions elsewhere in the codebase, so this
isn't adding value. In the "next" branch, this macro has been removed,
so this fixes a build error in that case.
This splits the previous null AbsoluteRawSyntax type into two categories
and removes the public null initializer and isNull method.
1. The default initializer of AbsoluteRawSyntax now create uninitialized
memory. This is exactly what we need since we just need to allocate
the memory to initialise it using the SyntaxDataRef::getChild method
wherever we use it.
2. Make Optional<AbsoluteRawSyntax> and Optional<SyntaxDataRef> zero-cost
wrappers around their underlying type. These use the old null type
to indicate a missing optional value.
Overall, I believe this makes the code both safer (we now enforce null
types properly in the type system) and potentially faster (although I
haven't been able to measure an improvement)
In contrast to SyntaxData, SyntaxDataRef is not memory-safe, but
designed to be fast. In particular, the following guarantees from
SyntaxData are being dropped:
- SyntaxDataRef does not retain the SyntaxArena containing its
RawSyntax. The user of SyntaxDataRef has to provide that guarantee.
However, that's usually pretty easily done by just retaining the
SyntaxArena of the tree's root node.
- The parent of a SyntaxDataRef must outlive the child node. This is
the more tricky constraint, but if a tree is just walked top to
bottom with nodes stored on the stack, this is given by the way the
stack is being unrolled.
These methods are super small and setting up the stack frame etc. takes
up the majority (or at least a significant amount) of their execution
time. So let's inline them.
Instead, only reference count the SyntaxArena that the RawSyntax nodes
live in. The user of RawSyntax nodes must guarantee that the SyntaxArena
stays alive as long as the RawSyntax nodes are being accessed.
During parse time, the SyntaxTreeCreator holds on to the SyntaxArena
in which it creates RawSyntax nodes. When inspecting a syntax tree,
the root SyntaxData node keeps the SyntaxArena alive. The change should
be mostly invisible to the users of the public libSyntax API.
This change significantly decreases the overall reference-counting
overhead. Since we were not able to free individual RawSyntax nodes
anyway, performing the reference-counting on the level of the
SyntaxArena feels natural.
Instead, reference count the SyntaxData's parent. This has a couple of
advantages:
1. We eliminate a const_cast that was potentially unsafe
2. It more closely resembles the architecture on the Swift side
3. It has the potential to be optimised further if the parent can be
accessed in an unsafe, non-reference-counted way