For example, a "jump to function in the global object" IR instruction could be initially implemented as a call to a handler that looks up the name of the function in the global object, and when it is found, the call to the handler is replaced by a direct jump to the function
I don't really like that idea because it seems to me to be rather tightly coupled with both the IR and the backend. It seems to me that you're suggesting having one or more specific IR instructions with corresponding backend support just for that one optimization. Not to mention wanting to perhaps have code directly in the global object or special function entry points again just for that one optimization.
I'm not sure what you have in mind as a "generic code patching functionality in the IR". The problem is that code patching is very low level (in the end you have to write real machine instructions). You need to know the size of the machine instructions, because code patching overwrites existing machine instructions with new machine instructions.
I'm not suggesting we directly have a mechanism to write over a sequence of IR instructions. I would propose that we instead brainstorm over what kinds of things we may want to do with code patching, and implement a small set of "patchable" IR instructions, so to speak. Some potential ideas:
- An IR value that can be patched/updated later. This might allow making a call site call a different functions at different times, or replacing a "constant" in a piece of code.
- A conditional branch (like an if instruction) that doesn't test any values and always branches the same way, until we toggle it to branch the other way instead (a patchable jump inside a function). Such patchable jumps could have more than two possible targets. This image comes to mind: http://visual.merriam-webster.com/images/transport-machinery/rail-transport/...