My guess is that the multithreaded-only design wasn't as good at exploiting the inherent per-tab parallelism. The original architecture probably had some synchronization points (perhaps related to the common GUI code) that did not allow processing each tab truly independently. Regarding memory allocation, yes, in theory one should be able to try to avoid sharing data across threads, which should eliminate serialization on memory allocation and deallocation. But I can easily imagine that in practice, in a codebase that was not explicitly designed to process each tab in parallel, you'll still end up sometimes sharing data across threads.
I imagine they could have instead changed the architecture to be multithreaded in such a way to avoid my imagined sequential bottlenecks, but performance is not the only goal in a multprocess architecture. Sandboxing is another design goal, and that cannot be fully achieved with a multithreaded design.
This is all speculation on my part, so if anyone who actually works on the Firefox codebase could correct me, that would be very welcomed.
I imagine they could have instead changed the architecture to be multithreaded in such a way to avoid my imagined sequential bottlenecks, but performance is not the only goal in a multprocess architecture. Sandboxing is another design goal, and that cannot be fully achieved with a multithreaded design.
This is all speculation on my part, so if anyone who actually works on the Firefox codebase could correct me, that would be very welcomed.