On 14/07/2013 21:27, Marvin Humphrey wrote:
I'm still tempted to do it for the sake of consistency. It would be nice to be able to say "Clownfish object struct types are completely opaque. Instance variables may only be accessed via IVARS."
We should say that anyway. Even if it is possible to get at the struct members of a Clownfish superclass, no other parcel should ever try that.
Haha, I feel your irritation. We've done all that work on thunks, which was largely motivated by the space issue! By the way, your work on the thunk benchmarking has never come up on the dev list (branch `method-dispatch-benchmark`). It was very illuminating!
Micro-benchmarks are always a bit dangerous, but it seems that on modern CPUs our current implementation of method dispatch is really fast and probably hard to beat. I think a loop with a single method call took about 6-7 cycles per iteration (Ivy Bridge, x64). This is surprising since computing the method address alone requires three memory loads with a latency of 4-5 cycles each (the third load depending on the first two). But because of branch prediction, the CPU can take a speculative branch immediately without having to wait for the memory loads. The branch target is validated later, so the loads can be pipelined.
In my experiments, precomputing the method address only saved a single cycle and sometimes wasn't faster at all. This is partly due to loop hoisting which might not be possible in real-life situations, but still surprising.
I don't think the use case of moving a novel method to a superclass is all that rare. It may not happen every day, but I'll bet it will happen multiple times over the lifetime of any project of significant size.
My guess is that most of the time this happens, there will be another non-compatible API change anyway.
I think it's important that we not burden developers with having to understand that kind of edge case detail. IMO, we have some serious work to do paring down the existing Clownfish header language, removing some experimental misfeatures that are no longer justified, and we should be reluctant to add any API complexity right now. I think it's premature to compromise the API for the sake of a space issue which probably won't affect performance. If you're amenable, can we please go with what we have now, with the understanding that we'll keep trying to find better implementations in the future?
OK, but this will mean to add MethodSpec structs for every method of a class. I think it's best to use separate structs for novel, overridden, and inherited methods then.
Nick
