Ticket #13868: trac_13868_tp_hooks_and_debug-typo.patch

File trac_13868_tp_hooks_and_debug-typo.patch, 9.9 KB (added by jpflori, 7 years ago)

Initial patch + typo fixed.

  • new file sage/ext/python_debug.h

    # HG changeset patch
    # User Volker Braun <vbraun.name@gmail.com>
    # Date 1356695633 0
    # Node ID 9e642bd44195386bc37eae4a26bdea7b3b534fc9
    # Parent  3c0d9a889422e99fc0bb83e6282706ddf066282b
    Deal with hooked tp_* functions when using a debug build of Python
    
    diff --git a/sage/ext/python_debug.h b/sage/ext/python_debug.h
    new file mode 100644
    - +  
     1/*
     2 * Workaround to handle Python preprocessor macros: Translate defined /
     3 * undefined into true / false
     4 */
     5
     6
     7#import <Python.h>
     8
     9#ifdef Py_DEBUG
     10    #define SAGE_Py_DEBUG Py_DEBUG
     11#else
     12    #define SAGE_Py_DEBUG 0
     13#endif
     14
     15#ifdef Py_REF_DEBUG
     16    #define SAGE_Py_REF_DEBUG Py_REF_DEBUG
     17#else
     18    #define SAGE_Py_REF_DEBUG 0
     19#endif
     20
     21#ifdef Py_TRACE_REFS
     22    #define SAGE_Py_TRACE_REFS Py_TRACE_REFS
     23    #define if_Py_TRACE_REFS_then_PyObject_INIT(obj, type) PyObject_INIT(obj, type)
     24#else
     25    #define SAGE_Py_TRACE_REFS 0
     26    #define if_Py_TRACE_REFS_then_PyObject_INIT(obj, type)
     27#endif
     28
     29#ifdef PYMALLOC_DEBUG
     30    #define SAGE_PYMALLOC_DEBUG PYMALLOC_DEBUG
     31#else
     32    #define SAGE_PYMALLOC_DEBUG 0
     33#endif
     34
     35#ifdef WITH_PYMALLOC
     36    #define SAGE_WITH_PYMALLOC PYMALLOC_DEBUG
     37#else
     38    #define SAGE_WITH_PYMALLOC 0
     39#endif
     40
     41
     42
  • new file sage/ext/python_debug.pxi

    diff --git a/sage/ext/python_debug.pxi b/sage/ext/python_debug.pxi
    new file mode 100644
    - +  
     1# Python can be built with extensive debugging support. This file lets
     2# Sage know about which debugging options are enabled.
     3#
     4# To enable debugging, build Sage with the SAGE_DEBUG environment
     5# variable set to "yes":
     6#
     7# [user@localhost:~/sage-x.y.z] export SAGE_DEBUG=yes && make
     8
     9
     10include "python_rich_object.pxi"
     11
     12cdef extern from "python_debug.h":
     13
     14    # This is what is generally meant by "a debug build" of Python.
     15    # Implies Py_REF_DEBUG, Py_TRACE_REFS, and PYMALLOC_DEBUG (if
     16    # WITH_PYMALLOC is enabled).  In addition, C assert()s are enabled.
     17    cdef bint Py_DEBUG "SAGE_Py_DEBUG"
     18
     19    # Turn on aggregate reference counting.  This arranges that extern
     20    # _Py_RefTotal hold a count of all references, the sum of
     21    # ob_refcnt across all objects.  Also checks after every decref to
     22    # verify that the refcount hasn't gone negative, and causes an
     23    # immediate fatal error if it has.
     24    cdef bint Py_REF_DEBUG "SAGE_Py_REF_DEBUG"
     25
     26    # Heavy reference debugging. Every PyObject grows two more
     27    # pointers, to maintain a doubly-linked list of all live
     28    # heap-allocated objects. Implies Py_REF_DEBUG.
     29    cdef bint Py_TRACE_REFS "SAGE_Py_TRACE_REFS"
     30
     31    # Conditionally call PyObject_INIT() if Py_TRACE_REFS is
     32    # enabled. This is necessary to initialize the aforementioned
     33    # double-linked list.
     34    void if_Py_TRACE_REFS_then_PyObject_INIT(RichPyObject *, RichPyTypeObject *)
     35
     36    # When this is enabled, calls to the PyObject_ memory routines are
     37    # handled by Python's own small-object allocator, while calls to
     38    # the PyMem_ memory routines are directed to the system malloc/
     39    # realloc/free.
     40    cdef bint WITH_PYMALLOC "SAGE_WITH_PYMALLOC"
     41
     42    # If this is also defined in addition to WITH_PYMALLOC, calls to
     43    # both PyObject_ and PyMem_ memory routines are directed to a
     44    # special debugging mode of Python's small-object
     45    # allocator. Requires WITH_PYMALLOC.
     46    cdef bint PYMALLOC_DEBUG "SAGE_PYMALLOC_DEBUG"
  • sage/ext/python_rich_object.pxi

    diff --git a/sage/ext/python_rich_object.pxi b/sage/ext/python_rich_object.pxi
    a b  
    4242    ctypedef struct RichPyObject "PyObject":
    4343        int ob_refcnt
    4444        RichPyTypeObject* ob_type
     45       
     46        # The following two fields are only present if Py_TRACE_REFS debugging is enabled
     47        RichPyObject* _ob_next
     48        RichPyObject* _ob_prev
    4549
    4650    cdef long Py_TPFLAGS_HAVE_GC
    4751
  • sage/rings/integer.pyx

    diff --git a/sage/rings/integer.pyx b/sage/rings/integer.pyx
    a b  
    139139include "../ext/python_list.pxi"
    140140include "../ext/python_number.pxi"
    141141include "../ext/python_int.pxi"
     142include "../ext/python_debug.pxi"
    142143include "../structure/coerce.pxi"   # for parent_c
    143144include "../libs/pari/decl.pxi"
    144145
     
    59395940
    59405941        memcpy(new, (<void*>global_dummy_Integer), sizeof_Integer )
    59415942
    5942         # This line is only needed if Python is compiled in debugging
    5943         # mode './configure --with-pydebug'. If that is the case a Python
    5944         # object has a bunch of debugging fields which are initialized
    5945         # with this macro. For speed reasons, we don't call it if Python
    5946         # is not compiled in debug mode. So uncomment the following line
    5947         # if you are debugging Python.
    5948 
    5949         #PyObject_INIT(new, (<RichPyObject*>global_dummy_Integer).ob_type)
    5950 
    59515943        # We take the address 'new' and move mpz_t_offset bytes (chars)
    59525944        # to the address of 'value'. We treat that address as a pointer
    59535945        # to a mpz_t struct and allocate memory for the _mp_d element of
     
    59765968
    59775969        (<__mpz_struct *>( <char *>new + mpz_t_offset) )._mp_d = <mp_ptr>mpz_alloc(GMP_LIMB_BITS >> 3)
    59785970
     5971    # This line is only needed if Python is compiled in debugging mode
     5972    # './configure --with-pydebug' or SAGE_DEBUG=yes. If that is the
     5973    # case a Python object has a bunch of debugging fields which are
     5974    # initialized with this macro.
     5975
     5976    if_Py_TRACE_REFS_then_PyObject_INIT\
     5977        (new, (<RichPyObject*>global_dummy_Integer).ob_type)
     5978
    59795979    # The global_dummy_Integer may have a reference count larger than
    59805980    # one, but it is expected that newly created objects have a
    59815981    # reference count of one. This is potentially unneeded if
  • sage/rings/real_double.pyx

    diff --git a/sage/rings/real_double.pyx b/sage/rings/real_double.pyx
    a b  
    3737"""
    3838 
    3939include '../ext/python_float.pxi'
     40include "../ext/python_debug.pxi"
    4041include '../ext/cdefs.pxi'
    4142include '../ext/stdsage.pxi'
    4243include '../ext/random.pxi'
     
    24112412########### Based on fast integer creation code   #########
    24122413######## There is nothing to see here, move along   #######
    24132414   
    2414 cdef extern from *:
    2415    
    2416     ctypedef struct RichPyObject "PyObject"
    2417  
    2418     # We need a PyTypeObject with elements so we can
    2419     # get and set tp_new, tp_dealloc, tp_flags, and tp_basicsize
    2420     ctypedef struct RichPyTypeObject "PyTypeObject":
    2421 
    2422         # We replace this one
    2423         PyObject*      (*    tp_new) ( RichPyTypeObject*, PyObject*, PyObject*)
    2424 
    2425         # Not used, may be useful to determine correct memory management function
    2426         RichPyObject *(*   tp_alloc) ( RichPyTypeObject*, size_t )
    2427 
    2428         # We replace this one
    2429         void           (*tp_dealloc) ( PyObject*)
    2430 
    2431         # Not used, may be useful to determine correct memory management function
    2432         void          (*    tp_free) ( PyObject* )
    2433 
    2434         # We set a flag here to circumvent the memory manager
    2435         long tp_flags
    2436 
    2437     cdef long Py_TPFLAGS_HAVE_GC
    2438 
    2439     # We need a PyObject where we can get/set the refcnt directly
    2440     # and access the type.
    2441     ctypedef struct RichPyObject "PyObject":
    2442         int ob_refcnt
    2443         RichPyTypeObject* ob_type
    2444          
    2445     # Allocation
    2446     RichPyObject* PyObject_MALLOC(int)
    2447 
    2448     # Useful for debugging, see below
    2449     void PyObject_INIT(RichPyObject *, RichPyTypeObject *)
    2450 
    2451     # Free
    2452     void PyObject_FREE(PyObject*)
     2415include "../ext/python_rich_object.pxi"
    24532416
    24542417# We use a global element to steal all the references
    24552418# from.  DO NOT INITIALIZE IT AGAIN and DO NOT REFERENCE IT!
     
    25192482
    25202483        memcpy(new, (<void*>global_dummy_element), sizeof(RealDoubleElement) )
    25212484
    2522         # This line is only needed if Python is compiled in debugging
    2523         # mode './configure --with-pydebug'. If that is the case a Python
    2524         # object has a bunch of debugging fields which are initialized
    2525         # with this macro. For speed reasons, we don't call it if Python
    2526         # is not compiled in debug mode. So uncomment the following line
    2527         # if you are debugging Python.
     2485    # This line is only needed if Python is compiled in debugging mode
     2486    # './configure --with-pydebug' or SAGE_DEBUG=yes. If that is the
     2487    # case a Python object has a bunch of debugging fields which are
     2488    # initialized with this macro.
    25282489
    2529         #PyObject_INIT(new, (<RichPyObject*>global_dummy_element).ob_type)
     2490    if_Py_TRACE_REFS_then_PyObject_INIT\
     2491        (new, (<RichPyObject*>global_dummy_element).ob_type)
    25302492
    25312493    # The global_dummy_element may have a reference count larger than
    25322494    # one, but it is expected that newly created objects have a
     
    25612523
    25622524    PyObject_FREE(o)
    25632525
    2564 hook_fast_tp_functions()
     2526from sage.misc.allocator cimport hook_tp_functions
     2527hook_tp_functions(global_dummy_element, NULL, <newfunc>&fast_tp_new, NULL, &fast_tp_dealloc, False)
    25652528
    2566 cdef hook_fast_tp_functions():
    2567     """
    2568    
    2569     """
    2570     global global_dummy_element
    2571 
    2572     cdef long flag
    2573 
    2574     cdef RichPyObject* o
    2575     o = <RichPyObject*>global_dummy_element
    2576 
    2577     # By default every object created in Pyrex is garbage
    2578     # collected. This means it may have references to other objects
    2579     # the Garbage collector has to look out for. We remove this flag
    2580     # as the only reference an Integer has is to the global Integer
    2581     # ring. As this object is unique we don't need to garbage collect
    2582     # it as we always have a module level reference to it. If another
    2583     # attribute is added to the Integer class this flag removal so as
    2584     # the alloc and free functions may not be used anymore.
    2585     # This object will still be reference counted.
    2586     flag = Py_TPFLAGS_HAVE_GC
    2587     o.ob_type.tp_flags = <long>(o.ob_type.tp_flags & (~flag))
    2588 
    2589     # Finally replace the functions called when an Integer needs
    2590     # to be constructed/destructed.
    2591     o.ob_type.tp_new = &fast_tp_new
    2592     o.ob_type.tp_dealloc = &fast_tp_dealloc
    25932529
    25942530def time_alloc_list(n):
    25952531    cdef int i