Use List instead of Rc<AssocListMut> in direct decl parser
Summary:
We currently aggregate the decls from a file being parsed in a mutable association list. Since our SmartConstructors state may be cloned (if the parser performs some speculative parsing, from which it may want to backtrack), we put the mutable list behind an Rc. When we want to add a parsed declaration, we use Rc::make_mut. If the refcount of the Rc is 1, make_mut will give us a mutable reference to the inner list. If it's greater than 1, make_mut will clone the inner list before giving us a mutable reference. This implementation was chosen on the assumption that we are generally not performing a speculative parse when we complete parsing of a toplevel declaration.
It turns out that this assumption is not true as often as we'd thought. There are several circumstances where the parser holds on to a previous checkpoint while it completes parsing of a toplevel declaration, so our refcount here is often greater than 1, leading to unnecessary clones. These waste time and needlessly inflate the size of our arena. We could deal with this by carefully auditing the FFP entrypoints and declaration parser, ensuring that only one copy of the parser state exists when we finish parsing each toplevel declaration. But this invariant would be fragile--it would be easy for someone to accidentally regress direct decl parser performance by holding on to a parser state copy for too long. It's more robust to use an immutable data structure to aggregate parsed decls. This diff uses an arena-allocated linked list type to do so.
Reviewed By: arxanas
Differential Revision:
D22796491
fbshipit-source-id:
c0ab98ba61b02ec5a1a0e54fcdaa11bd1aa8bc02