@mgaudet@discuss.systems @cfbolz@mastodon.social @jandem@mastodon.social @shriramk@mastodon.social @shu@mstdn.social
Another theme was rigidity.
The big wager in a tracing JIT for a dynamic language is that the code is secretly typed, and thus running the code suffices to type the program. For JS, a wild language, with subclassing, duck typing, undefined and null, and exuberant practitioners, this was a bad bet. Our tracing JIT was too rigid. It could not back off and compile less aggressively when its assumptions were wrong.
The nature of tracing is that the user's code goes fast when you have correctly guessed the types of *everything* the trace touches. Lots of high-stakes bets.
Say a script had a function argument that might be a function, an array, an object, or a string (which was absurdly common in JS library design, at least then). The JIT would do several traces, one for each type. If there were multiple arguments/variables/fields like that, this would explode combinatorially. We would then give up and stop tracing that code. We never tried to mark variables/instructions as having lots of observed type variation and then have the tracing JIT emit runtime PICs when touching those values. I always wondered why we didn't do this. I'm sure wiser people than me thought of it. Perhaps even this would have taken too long to stabilize; you have to watch the user fall off too many performance cliffs first.