| ▲ | someonebaggy 4 hours ago |
| Compilers are pretty good. Really good, even. But languages, even C, are abstractions, which necessarily constrain the level below. This threaded-code jump thing is just not possible to express in C. Even the best abstraction can often be beaten by something the abstraction can't express. Self-modifying code is one example. So is this threaded interpreter with its non-structured control flow. But it takes longer. It's more difficult. That's why the abstraction exists and is still very useful despite its limitations. |
|
| ▲ | Pannoniae 3 hours ago | parent [-] |
| Self-modifying code is a meme unless you're writing an obfuscator... (but even then you can hook the execution so it's a pretty low-tier anti-reversing effort ngl) For perf reasons it's the equivalent of shooting your leg off to lose weight. You're flushing the instruction cache and breaking prefetch, leading to a huge stall. Then you do it again. And again. It hasn't been in vogue since the 80s... |
| |
| ▲ | pfdietz 2 hours ago | parent | next [-] | | JIT compilers are essentially producing self-modifying programs (or, indeed, dynamically loaded libraries). Dynamic languages, like Common Lisp, where things can be redefined at run time likely require modification of running code to achieve high efficiency (the alternative is to just leave a general mechanism in place and accept the runtime overhead and loss of optimization opportunities from that.) | |
| ▲ | someonebaggy 3 hours ago | parent | prev [-] | | That depends how far in advance of running the code you're modifying it. You could see a JIT compiler as an extreme type of SMC. Or a Monero miner - its hashing algorithm relies on running randomly generated programs. | | |
| ▲ | Pannoniae 3 hours ago | parent [-] | | JIT and SMC are two different things because JIT is write-once-then-execute, SMC is write-many-then-execute-many. Even with reoptimisation like the JVM, you're not modifying the existing code but writing it onto a new page. That is the key difference, you're not modifying existing written-out instructions, you're creating new ones. | | |
| ▲ | someonebaggy 2 hours ago | parent [-] | | Consider a kernel that boots on several different machines with different capabilities. Patching the call instructions at init time, to point to either one version or another of a frequently used function, saves time. |
|
|
|