-
Notifications
You must be signed in to change notification settings - Fork 52
Description
In trying to split LOAD_ATTR_PROPERTY
into uops I encountered a problem: its guard needs to check that two cache entries match: func_version
must equal to fget->func_version
. Both func_version
and fget
are inline cache entries. Because Tier 2 IR is limited to a single cache entry per uop, we can't express this.
I tried to hack around it by loading fget
onto the stack, but of course that can't work: if the guard fails, there's an extra entry on top of the stack. A worse hack might pop it off the stack before calling DEOPT_IF()
, but that seems very unprincipled (what's the JIT going to do about this?).
Moreover it's possible that we're already at the pre-calculated max stack level. We could do a stack space check before pushing, growing the frame if neede (it would be safe to deopt if there's no room), but that also seems very unprincipled. (Also in a generator, whose frame has already been copied, we can't grow the frame.)
All in all I'm stumped here. It would be nice if we could translate this specialized opcode to Tier 2, since simple property getters would be good targets for function inlining in the optimizer (a common idiom being @property / def foo(self): return self._foo
) -- but we don't seem to have the machinery here.
Maybe @Fidget-Spinner has a thought here?