[Python-Dev] Type of range object members

"Martin v. Löwis" martin at v.loewis.de
Thu Aug 17 08:27:02 CEST 2006


Neal Norwitz schrieb:
> It would change the CheckExact()s from: op->ob_type ==
> global-variable, to: op->ob_type & CONSTANT == CONSTANT.  Check would
> be the same as the CheckExact, just with different constants.  The
> Check version would then drop the || condition.

Hmm. I don't see the for the FAST_SUBCLASS bit still.

I would set the relevant bit in the type object itself, and then have

#define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type)
#define PyInt_Check(op) \
        PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_INT_SUBCLASS)

Then, in inherit_special, I'd do

       type->tp_flags |= base->tp_flags & Py_TPFLAGS_FAST_SUBCLASS_MASK;

So you would have a pointer comparison for the exact check, and the
bit mask check for the subtype check.

It's likely that the pointer comparison is still more efficient: It
does *not*, normally, need to read a global variable to get the address
of PyInt_Type.

Currently, on x86, with non-PIC code on Linux, the pointer check compiles as

        cmpl    $PyInt_Type, 4(%eax)   ; %eax is the object

where the linker fills the address of PyInt_Type into the machine
instruction. OTOH, the access to the flags compiles as

        movl    4(%eax), %eax          ; %eax is the object
        movl    84(%eax), %eax
        andl    $2013265920, %eax
        cmpl    $2013265920, %eax

Even with PIC code, the address check is still more efficient:

        movl    PyInt_Type at GOT(%ecx), %eax
        cmpl    %eax, 4(%edx)          ; %edx is the object


Regards,
Martin


More information about the Python-Dev mailing list