Someone correct me if I am wrong, but self-mutating code is not as uncommon as the author portrays it.
I thought the whole idea of hotspot optimization in a compiler is essentially self-mutating code.
Also, I spent a moderately successful internship at Microsoft working on dynamic assemblies. I never got deep enough into that to fully understand when and how customers where actually using it.
A program that can generate, compile, and execute new code is nothing special in the Common Lisp world. One can build lambda expressions, invoke the compile function on them, and call the resulting compiled functions. One can even assign these functions to the symbol-function slot of symbols, allowing them to be called from pre-existing code that had been making calls to that function named by that symbol.
I know that no other language can match Lisp, but many languages can generate and execute new code, if they're interpreted. Compile, too, if they're JITted. They all require quite a bit of runtime support though.
It sometimes can, but you then have to balance the time spent optimizing against the time spent actually doing whatever you were optimizing.
Also on modern chips you must wait quite a number of cycles before executing modified code or endure a catastrophic performance hit. This is ok for loops and stuff, but makes a lot of the really clever stuff pointless.
The debuggers software breakpoints _are_ self-modifying code :)
I used GNU lightning library once for such optimisation. I think it was ICFPC 2006 task. I had to write an interpreter for virtual machine. Naive approach worked but was slow, so I decided to speed it up a bit using JIT. It wasn't a 100% JIT, I think I just implemented it for loops but it was enough to tremendously speed it up.
Programs from the 80s-90s are likely to have such tricks. I have done something similar to "hardcode" semi-constants like frame sizes and quantisers in critical loops related to audio and video decompression, and the performance gain is indeed measurable.
Say you set a value for some reason. Later you have to check IF it is set. If the condition needs to be checked many times you replace it with the code (rather than set a value to check some place). If you need to check if something is still true repeatedly you replace the condition check with no-ops when it isn't true.
Also funny are insanely large loop unrolls with hard coded valued. You could make a kind of rainbow table of those.
You mean you somehow avoided a load. But what if the constant was already placed in a register ? Also how could you pinpoint the reference to your constant in the machine code ? I'm quite profane about all this.
I’ve been thinking a lot about this topic lately, even studying how executables look on arm macOS. My motivation was exploring truly fast incremental compilation for native code.
The only way to do this now on macOS is remapping whole pages as JIT. This makes it quite a challenge but still it might work…
It's impressive how well laid out the content in this article is. The spacing, tables, and code segments all look pristine to me, which is especially helpful given how dense and technical the content is.
Also, I spent a moderately successful internship at Microsoft working on dynamic assemblies. I never got deep enough into that to fully understand when and how customers where actually using it.
https://learn.microsoft.com/en-us/dotnet/fundamentals/reflec...
Also on modern chips you must wait quite a number of cycles before executing modified code or endure a catastrophic performance hit. This is ok for loops and stuff, but makes a lot of the really clever stuff pointless.
The debuggers software breakpoints _are_ self-modifying code :)
Say you set a value for some reason. Later you have to check IF it is set. If the condition needs to be checked many times you replace it with the code (rather than set a value to check some place). If you need to check if something is still true repeatedly you replace the condition check with no-ops when it isn't true.
Also funny are insanely large loop unrolls with hard coded valued. You could make a kind of rainbow table of those.
You mean you somehow avoided a load. But what if the constant was already placed in a register ? Also how could you pinpoint the reference to your constant in the machine code ? I'm quite profane about all this.
The only way to do this now on macOS is remapping whole pages as JIT. This makes it quite a challenge but still it might work…