Currently if we get a type change in a script while inside a compiled version of it, we have to immediately recompile and do on stack replacement. This is sub-optimal in a couple ways:
- Makes the compiler vulnerable to recompilation thrashing. Currently there is a gigantic regression on sunspider-crypto-md5 because the core_md5 function starts repeatedly reading holes out of an array at many sites well after it was initially compiled. Will kludge around this shortly, but it would be better to just rejoin into the interpreter and let it find all the holes.
- Bad/no story for handling OOM in inference. If we run out of memory during inference then all its information is invalidated, and we basically need to disable inference and recompile the entire compartment. This is of course problematic if we just had an OOM. Instead, we could rejoin all JIT frames to the interpreter, throw away all compiled code, and then compile things later on as necessary.
Instead, we could use a trampoline that reads data off the VMFrame and calls Interpret. The main complexity here is in dealing with rejoins into the middle of an opcode, e.g. INCGNAME and friends.
Sounds like a reason to get rid of those opcodes!
Created attachment 530829 [details] [diff] [review]
WIP patch which removes on-stack recompilation, adds an interpreter trampoline (the Interpoline!) and makes all type-manipulating inference calls infallible (most of the diff). Still missing are handlers for most of the exotic states the stack can be in after making a stub call.
Created attachment 531041 [details] [diff] [review]
JM patch. This only updates the trampolines for Mac/Linux x86/x64 and Windows x86, can take a guess at other platforms later but at least Win64 seems to use a different ABI and it's better to have machines to test these trampolines on.
Reset the use count for scripts after discarding JIT code (except when recompiling in order to inline calls), so that the script can warm back up some before recompiling. This combines script->callCount and compartment->backEdgeTable into a single script->useCount, as there is no simple way to clear a script's entries in the back edge table (entries in this table stick around even after the script itself has been destroyed).