|
From: Donal K. F. <don...@ma...> - 2017-06-06 22:39:05
|
On 06/06/2017 02:31, Kevin Kenny wrote:
> Tonight's commits eliminate callframes from 'entry', 'returnCode',
> 'returnOptions', 'return' and 'returnException' if the only callframe in
> the procedure is the entry callframe. (Still to come: detecting that
> invoked commands don't need the callframe at all.)
>
> Many of our demo cases buy at least some performance back with this change.
I've got my work on building an LVT properly working too (was just
missing some reference count handling) which means we can avoid having
to ckalloc() on entrance to our compiled procedures, and that gains most
of the other remaining performance back; the only problem cases left
seem to be in the [comps] procedure, and that's deliberately a bunch of
tricky cases (where the #1 target is ‘correct answer at all’).
The LVT metadata generation wasn't simple. :-(
I don't think we're ready for merging back to the trunk yet. Still needs
a few extra things adding in there, particularly including the
definition of the list of argument words so that [info level] can report
them; it's also one of the things moderately likely to be used in a
recursive call in Tcl as it is a debugging tool...
> I noticed that the code issuer was looking for an output type of NOTHING
> on the 'entry' instruction. I changed that to looking for the empty
> operand {}. If I put Nothing on the left-hand side, type analysis
> obligingly assigned the type 'CALLFRAME' to the symbol 'Nothing' and
> propagated that nonsense everywhere. I left 'Nothing' on the places
> where it appears on the right-hand side, so only 'entry' is affected so
> far (When I do the next step, I'm sure that I'll find the same issue
> with 'invoke', but I'm not there yet.)
I freely admit that I didn't think hard about how to detect that we were
in callframe-less mode. If that works better for you, that's what it
should be. However, if we're going to be consistently (across all the
places that might take a CALLFRAME or might not) using the empty string
to indicate that we're in that mode, we should teach the IsCallFrame
check method (the callframe() function delegates to it) to do the test
that way so that we can use the same approach everywhere. Consistency is
useful if we don't want to go completely crazy. ;-)
Also, be aware that the variables listed in the bytecode include
temporaries (they have the “temp” flag set) which shouldn't be saved and
resuscitated around “invoke” calls, as they can't be touched by external
code as they have no name at all. They're artefacts of Tcl's
implementation, not things we need to treat as standard Tcl vars.
However, it's not a problem to allocate a slot for them (and in fact I
don't really need the variable-list argument to “enter”; I can — must,
really — read the same info out of the original bytecode anyway in order
to get the flag bits for the LVT metadata).
Donal.
|