A lot of code on the web is very cold (executed once or twice) and for such code the Baseline Interpreter would add some overhead (requires allocating a JitScript storing the IC data for example and we would then spend more time in IC code as well). It's possible this could be mitigated or fixed with additional work, but we need to keep the C++ interpreter anyway (not all platforms have a JIT backend and it's useful for differential testing) so it's not a priority right now.
A lot of code is run once, so the initial compilation cost is potentially more expensive than just the process of compilation, without even running the generated code, and if not that then compilation+execution is also longer than just interpreting.
There are also benefits for performance. If you haven’t run any of the code yet (through the interpreter), the baseline portion of the JIT has no knowledge of the code that is running, and so has to make a bunch of static guesses and (if you look at the old baseline JIT in JSC) include a lot of code for various common cases that may happen. Eg in the JSC case every arithmetic op include the entire code for both integer and floating point arithmetic inline. That bites you in a few ways: the guessing type info means that you have poorly chosen branch ordering (eg you put integer logic in the middle of the “fast” path for something that is floating point), and you simply generate more code which itself takes more time to produce, and also results in increased icache pressure which hurts runtime performance.
I haven’t read the entire article yet, but the JSC interpreter is written in a pseudo assembly so it can do an on stack replacement to switch into jotted code more or less anywhere during execution as the wonders of assembly means you can guarantee identical layout.
Allocating this additional struct is a waste of memory for a function that is only executed a handful of times, without ever actually using that information for optimizing.