Juergen Boemmels wrote:
Leopold Toetsch <[EMAIL PROTECTED]> writes:
What happens if you try to use it on an object which has no real
components like a bitvector or a packed structure?
The substituted code for an aggregate is: set Py, P1[k1] and for a non keyed operand: set Py, {N,S,I}1
There will always be a pack-unpack cycle. On the other hand, is there any case where this pack-unpack cycle can be avoided?
Yes, if the 3rd operand is an integer, we have some opcodes like add_p_p_i
The newly created PMC is of type PerlUndef. Is this the correct behavior or shouldn't it be the same type as the old element in the Component? Something like this.
As in my example, the LHS might and does not exist yet, so you can't get the type of it. And The PerlUndef convert's itself to the result of the operation automagically, so it's IMHO the correct way to do it.
With an approach like this, we could cut down the VTABLE to roughly 1/3 of it's current size. The _keyed entrys would only consist of the set_.._keyed{,_int} variants plus exists_keyed and defined_keyed. And, we would never have the opcode explosion to 64 times of current size.
Instead of 1 opcode and 1 vtable-lookup with a quite complex vtable-function you have 6 opcodes and 5 vtable lookups with simple vtable-functions.
Take the "new px, .PerlUndef" out of the calculation, it can be done only once. The vtable lookup's are there, either hidden in a complex opcode, or explictely like in my solution.
So the difference are +4 opcodes worst case. But opcode dispatch is really fast. A better cache locality will bring us back this speed difference.
... Also no vtable function has to decide wether its called with 1, 2 or 3 keyed elements.
Yes, another advantage, I didn't think of. Currently all _keyed vtable calls have to check, it the key is really there. This could be tossed.
bye b.
leo