On Oct 16, 2004, at 4:47 AM, Leopold Toetsch wrote:
String, number (and PMC) constants are all addressed in terms of the compiling interpreter.
...
When we do an eval() e.g. in a loop, we have to create a new constant table (and recycle it later, which is a different problem). Running such a compiled piece of code with different threads would currently do the wrong thing.
The correct constant table depends on the code segment, rather than the specific interpreter, right?
Yes.
...That means that referencing the absolute address of the const table entry would be correct for JIT code no matter the executing thread, but getting the const table from the compiling interpreter is wrong if that interpreter isn't holding a reference to the corresponding code segment.
Thinking more about that I've to admit that my above conclusion is very likely wrong. When a piece of code gets compiled, we can say that we are creating a read-only data structure (code, constants, metadata). This data structure can be shared between different threads and using absolute addresses for the constants is ok.
Nethertheless we have to create managed objects (a Packfile PMC) so that we can recycle unused eval-segments. And we have to protect the packfile dictionary with mutexes, when this managing structure changes i.e. when new segments gets chained into this list or when they get destroyed.
Access to constants in the constant table is not only a problem for the JIT runcore, its a lengthy operation for all code, For a string constant at PC[i]:
interpreter->code->const_table->constants[PC[i]]->u.string
So for JIT and prederefed cores that's not a problem.
OTOH it might be better to just toss all the constant table access in all instructions, except:
set_n_nc set_s_sc set_p_pc # alias set_p_kc
This would reduce the interpreter size significantly (compare the size of core_ops_cgp.o with core_ops_cg.o).
Reducing the size is good, but this doesn't overall reduce the number of accesses to the constant table, just changes which op is doing them.
Not quite, e.g:
set P0["foo"], "bar" set S0, P0["foo"]
are 3 accesses to the constant table. It would be
set S1, "foo" set S2, "bar" set P0[S1], S2 set S0, P0[S1]
with 2 accesses as long as there is no pressure on the register allocator.
The assembler could still allow all constant variations of opcodes and just translate it.
For this we'd need a special register to hold the loaded constant, so that we don't overwrite a register which is in use.
No, just the registers we have anyway,
JEff
leo