June 13, 2005

WCB: Overridable opcodes

One of the things originally planned for parrot was the capability of overriding the functions attached to most of the opcodes at runtime, lexically scoped. That is, for any particular block (or, more likely, subroutine or method) your code could change the definition of, say, the tangent opcode, or the read opcode.

That sounds silly, doesn't it? I mean, to be able to change, at runtime, the basic components of the interpreter. That's insane!

Or not. First, because you're not allowed to override them all. The basics (any of the ops that can be JITted) are fixed, so you can't go changing how bsr or exit works. Second, remember, as far as parrot is concerned, an opcode is just a low level function with a fixed signature and fast calling scheme. That's it. Nothing at all fancy. "Opcodes" are just a combination of core engine functions and basic (but extendable) runtime library. (Since you do, after all, want your low-level runtime library functions to be as fast to call as absolutely necessary)

Sure, you could, if you want, use the more generic function call scheme to call those functions instead of making them callable using the opcode function mechanism, but that just means that the function calls are slower. (As parrot doesn't have a faster call scheme than the one opcode functions use. Even if you chopped bits out of the current calling conventions there's still more overhead, and you can't get rid of it) Somehow just doesn't make sense to me...

Anyway, on top of private opcode definitions (in those cases where you want to have your own ops) this allows for a lot of instrumentation to be applied. With the exception of that core set that you can't change, everything else is potentially up for grabs, and that means that if you do want to get in the way of how code executes (lexically!) you can. While this certainly isn't something you'd want to do a lot, actually being able to do it can come in handy. (Granted, in those situations you hope you're never in. Alas those are the ones you inevitably end up dealing with)

The cost is that you can't JIT those ops, nor can you inline their bodies in the switch or computed goto cores. This is generally an acceptable cost, since the ops which you do this with are ones that you don't execute often enough for the performance penalty to be offset by the potential utility of overriding the ops. (Especially since this will most often be done with runtime library functions, in which case they're probably not JITtable anyway, and even with the slowdown from the indirect low-level function call it's still faster than a parrot function call)

Posted by Dan at June 13, 2005 04:05 PM | TrackBack (0)

Dan, perhaps you could suggest a new name for these non-core opcodes, like optimized calls - opcalls. It seems like the innovation of having this fast call path may be lost because people see "opcode" and miss the distinction you make here.


Posted by: Kris at June 16, 2005 12:12 PM

Just realized I posted to the wrong article, I meant to target WWIT: All those opcodes.

Posted by: Kris at June 16, 2005 12:23 PM

I'm out of things completely, so I'll leave it up to other people to make suggestions.

As to whatever's going on, well... I'm out of things. Chip's not stupid. If he's making changes and redoing design I shall assume he's got good reasons to assume that what's there isn't worth keeping. (The alternative is to assume a certain amount of contempt for my design, and I think I'd rather not go there right now)

Posted by: Dan at June 16, 2005 12:35 PM