Jason Gloudon wrote:

On Thu, Jan 30, 2003 at 10:07:26AM +0100, Leopold Toetsch wrote:

code_start = interpreter->code->base.data; // new syntax
while (offs)
     offs = interp->func_table[*(code_start+offs)](offs, ..)

It's unclear to me whether you are saying the opcode functions would still be
passed the PC or offs(et) ? If you pass the offset, the opcode functions will
have to re-calculate the PC in order to access opcode arguments.

The opcode functions do now address the registers relative to the PC = cur_opcode = the absolute opcode pointer, e.g.

#define IREG(i) interpreter->ctx.int_reg.registers[cur_opcode[i]]

which would then be

#define IREG(i) interpreter->ctx.int_reg.registers[code_start[offs+i]]

So clearly only the offset is passed to opfuntions.

Yes, I did miss this part of probable slowdown.
No, I don't think, it will be much - and the assembler (i.e.) imcc
could provide the index [offs + i] - relative to code start,
*if* it really would slow down the basic run loops.

But and again, please have a look at the different timings of run loops. We are speaking here of magnitudes from 10 - 800, only the slow loops have a negative impact - if even and if the program is loop bound, which IMHO no real world program will be.


Changing the addressing scheme to opcode offsets relative to code
start would simplify all kinds of (non local) control flow changes.

How would non local control flow be simplified ? You would still have to leave
the runloop because the bytecode base has changed and code_start would no
longer be correct.

A direct jump to a different code segment is currently not feasible because of the absolute pointer to the byte code is passed around, which additionally depends on the running run loop. E.g. prederefed code, when predereferencing is not done has a pointer to the convert routine which dereferences registers and changes the function pointer, which then points to the real CPrederef opcode function.
When here a code segment change op comes in, it is either hard or impossible to do it right.
When all addresses involved are in offsets relative to code_start (what ever this is, compiled JIT or prederefed code), the operations itself can do the intercodesegment jump by changing offset plus codestart, that's all.

And, formost, my proposal makes it all simpler and natural: Bytecode and especially branches are all in terms of opcode offsets, our runloops are not. Here is the point were all possible complications start.
Currently the various OpTrans/*.pm functions take care of providing most of these pointer manipulations (which e.g. fail for PBC compiled to native C, when non trivial branches are involved). Passing just the offset would unit this can of worms.
And as I did say: JIT and compiled C code only have offsets in bytecode. Opcode pointers are pointers to machine code, you cant't calculate with these and get back the offset to some byte code location. The passing "PC concept fails" here totally.

leo

Reply via email to