LCOV - code coverage report
Current view: top level - Include/internal - pycore_object.h (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 54 54 100.0 %
Date: 2022-07-20 13:12:14 Functions: 13 13 100.0 %
Branches: 10 10 100.0 %

           Branch data     Line data    Source code
       1                 :            : #ifndef Py_INTERNAL_OBJECT_H
       2                 :            : #define Py_INTERNAL_OBJECT_H
       3                 :            : #ifdef __cplusplus
       4                 :            : extern "C" {
       5                 :            : #endif
       6                 :            : 
       7                 :            : #ifndef Py_BUILD_CORE
       8                 :            : #  error "this header requires Py_BUILD_CORE define"
       9                 :            : #endif
      10                 :            : 
      11                 :            : #include <stdbool.h>
      12                 :            : #include "pycore_gc.h"            // _PyObject_GC_IS_TRACKED()
      13                 :            : #include "pycore_interp.h"        // PyInterpreterState.gc
      14                 :            : #include "pycore_pystate.h"       // _PyInterpreterState_GET()
      15                 :            : #include "pycore_runtime.h"       // _PyRuntime
      16                 :            : 
      17                 :            : #define _PyObject_IMMORTAL_INIT(type) \
      18                 :            :     { \
      19                 :            :         .ob_refcnt = 999999999, \
      20                 :            :         .ob_type = (type), \
      21                 :            :     }
      22                 :            : #define _PyVarObject_IMMORTAL_INIT(type, size) \
      23                 :            :     { \
      24                 :            :         .ob_base = _PyObject_IMMORTAL_INIT(type), \
      25                 :            :         .ob_size = size, \
      26                 :            :     }
      27                 :            : 
      28                 :            : PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
      29                 :            :     const char *func,
      30                 :            :     const char *message);
      31                 :            : 
      32                 :            : #define _Py_FatalRefcountError(message) \
      33                 :            :     _Py_FatalRefcountErrorFunc(__func__, (message))
      34                 :            : 
      35                 :            : static inline void
      36                 :   10128997 : _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
      37                 :            : {
      38                 :            :     _Py_DECREF_STAT_INC();
      39                 :            : #ifdef Py_REF_DEBUG
      40                 :            :     _Py_RefTotal--;
      41                 :            : #endif
      42         [ +  + ]:   10128997 :     if (--op->ob_refcnt != 0) {
      43                 :            :         assert(op->ob_refcnt > 0);
      44                 :            :     }
      45                 :            :     else {
      46                 :            : #ifdef Py_TRACE_REFS
      47                 :            :         _Py_ForgetReference(op);
      48                 :            : #endif
      49                 :   10119199 :         destruct(op);
      50                 :            :     }
      51                 :   10128997 : }
      52                 :            : 
      53                 :            : static inline void
      54                 :  309769543 : _Py_DECREF_NO_DEALLOC(PyObject *op)
      55                 :            : {
      56                 :            :     _Py_DECREF_STAT_INC();
      57                 :            : #ifdef Py_REF_DEBUG
      58                 :            :     _Py_RefTotal--;
      59                 :            : #endif
      60                 :  309769543 :     op->ob_refcnt--;
      61                 :            : #ifdef Py_DEBUG
      62                 :            :     if (op->ob_refcnt <= 0) {
      63                 :            :         _Py_FatalRefcountError("Expected a positive remaining refcount");
      64                 :            :     }
      65                 :            : #endif
      66                 :  309769543 : }
      67                 :            : 
      68                 :            : PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
      69                 :            : PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
      70                 :            : 
      71                 :            : /* Update the Python traceback of an object. This function must be called
      72                 :            :    when a memory block is reused from a free list.
      73                 :            : 
      74                 :            :    Internal function called by _Py_NewReference(). */
      75                 :            : extern int _PyTraceMalloc_NewReference(PyObject *op);
      76                 :            : 
      77                 :            : // Fast inlined version of PyType_HasFeature()
      78                 :            : static inline int
      79                 : 2518012457 : _PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
      80                 : 2518012457 :     return ((type->tp_flags & feature) != 0);
      81                 :            : }
      82                 :            : 
      83                 :            : extern void _PyType_InitCache(PyInterpreterState *interp);
      84                 :            : 
      85                 :            : 
      86                 :            : /* Inline functions trading binary compatibility for speed:
      87                 :            :    _PyObject_Init() is the fast version of PyObject_Init(), and
      88                 :            :    _PyObject_InitVar() is the fast version of PyObject_InitVar().
      89                 :            : 
      90                 :            :    These inline functions must not be called with op=NULL. */
      91                 :            : static inline void
      92                 :  889173207 : _PyObject_Init(PyObject *op, PyTypeObject *typeobj)
      93                 :            : {
      94                 :            :     assert(op != NULL);
      95                 :  889173207 :     Py_SET_TYPE(op, typeobj);
      96         [ +  + ]:  889173207 :     if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
      97                 :   42983880 :         Py_INCREF(typeobj);
      98                 :            :     }
      99                 :  889173207 :     _Py_NewReference(op);
     100                 :  889173207 : }
     101                 :            : 
     102                 :            : static inline void
     103                 :  307829448 : _PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
     104                 :            : {
     105                 :            :     assert(op != NULL);
     106                 :  307829448 :     Py_SET_SIZE(op, size);
     107                 :  307829448 :     _PyObject_Init((PyObject *)op, typeobj);
     108                 :  307829448 : }
     109                 :            : 
     110                 :            : 
     111                 :            : /* Tell the GC to track this object.
     112                 :            :  *
     113                 :            :  * The object must not be tracked by the GC.
     114                 :            :  *
     115                 :            :  * NB: While the object is tracked by the collector, it must be safe to call the
     116                 :            :  * ob_traverse method.
     117                 :            :  *
     118                 :            :  * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags
     119                 :            :  * because it's not object header.  So we don't use _PyGCHead_PREV() and
     120                 :            :  * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
     121                 :            :  *
     122                 :            :  * See also the public PyObject_GC_Track() function.
     123                 :            :  */
     124                 :  675536062 : static inline void _PyObject_GC_TRACK(
     125                 :            : // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
     126                 :            : #ifndef NDEBUG
     127                 :            :     const char *filename, int lineno,
     128                 :            : #endif
     129                 :            :     PyObject *op)
     130                 :            : {
     131                 :            :     _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
     132                 :            :                           "object already tracked by the garbage collector",
     133                 :            :                           filename, lineno, __func__);
     134                 :            : 
     135                 :  675536062 :     PyGC_Head *gc = _Py_AS_GC(op);
     136                 :            :     _PyObject_ASSERT_FROM(op,
     137                 :            :                           (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
     138                 :            :                           "object is in generation which is garbage collected",
     139                 :            :                           filename, lineno, __func__);
     140                 :            : 
     141                 :  675536062 :     PyInterpreterState *interp = _PyInterpreterState_GET();
     142                 :  675536062 :     PyGC_Head *generation0 = interp->gc.generation0;
     143                 :  675536062 :     PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
     144                 :  675536062 :     _PyGCHead_SET_NEXT(last, gc);
     145                 :  675536062 :     _PyGCHead_SET_PREV(gc, last);
     146                 :  675536062 :     _PyGCHead_SET_NEXT(gc, generation0);
     147                 :  675536062 :     generation0->_gc_prev = (uintptr_t)gc;
     148                 :  675536062 : }
     149                 :            : 
     150                 :            : /* Tell the GC to stop tracking this object.
     151                 :            :  *
     152                 :            :  * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING
     153                 :            :  * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.
     154                 :            :  *
     155                 :            :  * The object must be tracked by the GC.
     156                 :            :  *
     157                 :            :  * See also the public PyObject_GC_UnTrack() which accept an object which is
     158                 :            :  * not tracked.
     159                 :            :  */
     160                 :  673285221 : static inline void _PyObject_GC_UNTRACK(
     161                 :            : // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
     162                 :            : #ifndef NDEBUG
     163                 :            :     const char *filename, int lineno,
     164                 :            : #endif
     165                 :            :     PyObject *op)
     166                 :            : {
     167                 :            :     _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op),
     168                 :            :                           "object not tracked by the garbage collector",
     169                 :            :                           filename, lineno, __func__);
     170                 :            : 
     171                 :  673285221 :     PyGC_Head *gc = _Py_AS_GC(op);
     172                 :  673285221 :     PyGC_Head *prev = _PyGCHead_PREV(gc);
     173                 :  673285221 :     PyGC_Head *next = _PyGCHead_NEXT(gc);
     174                 :  673285221 :     _PyGCHead_SET_NEXT(prev, next);
     175                 :  673285221 :     _PyGCHead_SET_PREV(next, prev);
     176                 :  673285221 :     gc->_gc_next = 0;
     177                 :  673285221 :     gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
     178                 :  673285221 : }
     179                 :            : 
     180                 :            : // Macros to accept any type for the parameter, and to automatically pass
     181                 :            : // the filename and the filename (if NDEBUG is not defined) where the macro
     182                 :            : // is called.
     183                 :            : #ifdef NDEBUG
     184                 :            : #  define _PyObject_GC_TRACK(op) \
     185                 :            :         _PyObject_GC_TRACK(_PyObject_CAST(op))
     186                 :            : #  define _PyObject_GC_UNTRACK(op) \
     187                 :            :         _PyObject_GC_UNTRACK(_PyObject_CAST(op))
     188                 :            : #else
     189                 :            : #  define _PyObject_GC_TRACK(op) \
     190                 :            :         _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op))
     191                 :            : #  define _PyObject_GC_UNTRACK(op) \
     192                 :            :         _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op))
     193                 :            : #endif
     194                 :            : 
     195                 :            : #ifdef Py_REF_DEBUG
     196                 :            : extern void _PyDebug_PrintTotalRefs(void);
     197                 :            : #endif
     198                 :            : 
     199                 :            : #ifdef Py_TRACE_REFS
     200                 :            : extern void _Py_AddToAllObjects(PyObject *op, int force);
     201                 :            : extern void _Py_PrintReferences(FILE *);
     202                 :            : extern void _Py_PrintReferenceAddresses(FILE *);
     203                 :            : #endif
     204                 :            : 
     205                 :            : static inline PyObject **
     206                 :   45224634 : _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
     207                 :            : {
     208                 :   45224634 :     Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
     209                 :   45224634 :     return (PyObject **)((char *)op + offset);
     210                 :            : }
     211                 :            : 
     212                 :            : // Fast inlined version of PyObject_IS_GC()
     213                 :            : static inline int
     214                 : 5687375176 : _PyObject_IS_GC(PyObject *obj)
     215                 :            : {
     216                 : 5687375176 :     return (PyType_IS_GC(Py_TYPE(obj))
     217   [ +  +  +  + ]: 6386574231 :             && (Py_TYPE(obj)->tp_is_gc == NULL
     218         [ +  + ]:  699199055 :                 || Py_TYPE(obj)->tp_is_gc(obj)));
     219                 :            : }
     220                 :            : 
     221                 :            : // Fast inlined version of PyType_IS_GC()
     222                 :            : #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
     223                 :            : 
     224                 :            : static inline size_t
     225                 :  634172532 : _PyType_PreHeaderSize(PyTypeObject *tp)
     226                 :            : {
     227                 :  634172532 :     return _PyType_IS_GC(tp) * sizeof(PyGC_Head) +
     228                 :  634172532 :         _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *);
     229                 :            : }
     230                 :            : 
     231                 :            : void _PyObject_GC_Link(PyObject *op);
     232                 :            : 
     233                 :            : // Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL));
     234                 :            : extern int _Py_CheckSlotResult(
     235                 :            :     PyObject *obj,
     236                 :            :     const char *slot_name,
     237                 :            :     int success);
     238                 :            : 
     239                 :            : // PyType_Ready() must be called if _PyType_IsReady() is false.
     240                 :            : // See also the Py_TPFLAGS_READY flag.
     241                 :            : #define _PyType_IsReady(type) ((type)->tp_dict != NULL)
     242                 :            : 
     243                 :            : // Test if a type supports weak references
     244                 :   47747567 : static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
     245                 :   47747567 :     return (type->tp_weaklistoffset > 0);
     246                 :            : }
     247                 :            : 
     248                 :            : extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
     249                 :            : 
     250                 :            : extern int _PyObject_InitializeDict(PyObject *obj);
     251                 :            : extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
     252                 :            :                                           PyObject *name, PyObject *value);
     253                 :            : PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
     254                 :            :                                         PyObject *name);
     255                 :            : 
     256                 :  528790963 : static inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj)
     257                 :            : {
     258                 :            :     assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
     259                 :  528790963 :     return ((PyDictValues **)obj)-4;
     260                 :            : }
     261                 :            : 
     262                 :  226774640 : static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj)
     263                 :            : {
     264                 :            :     assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
     265                 :  226774640 :     return ((PyObject **)obj)-3;
     266                 :            : }
     267                 :            : 
     268                 :            : #define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3)
     269                 :            : 
     270                 :            : extern PyObject ** _PyObject_DictPointer(PyObject *);
     271                 :            : extern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg);
     272                 :            : extern void _PyObject_ClearInstanceAttributes(PyObject *self);
     273                 :            : extern void _PyObject_FreeInstanceAttributes(PyObject *self);
     274                 :            : extern int _PyObject_IsInstanceDictEmpty(PyObject *);
     275                 :            : extern PyObject* _PyType_GetSubclasses(PyTypeObject *);
     276                 :            : 
     277                 :            : // Access macro to the members which are floating "behind" the object
     278                 :            : #define _PyHeapType_GET_MEMBERS(etype) \
     279                 :            :     ((PyMemberDef *)(((char *)(etype)) + Py_TYPE(etype)->tp_basicsize))
     280                 :            : 
     281                 :            : PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);
     282                 :            : 
     283                 :            : /* C function call trampolines to mitigate bad function pointer casts.
     284                 :            :  *
     285                 :            :  * Typical native ABIs ignore additional arguments or fill in missing
     286                 :            :  * values with 0/NULL in function pointer cast. Compilers do not show
     287                 :            :  * warnings when a function pointer is explicitly casted to an
     288                 :            :  * incompatible type.
     289                 :            :  *
     290                 :            :  * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict
     291                 :            :  * function signature checks. Argument count, types, and return type must
     292                 :            :  * match.
     293                 :            :  *
     294                 :            :  * Third party code unintentionally rely on problematic fpcasts. The call
     295                 :            :  * trampoline mitigates common occurences of bad fpcasts on Emscripten.
     296                 :            :  */
     297                 :            : #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
     298                 :            : #define _PyCFunction_TrampolineCall(meth, self, args) \
     299                 :            :     _PyCFunctionWithKeywords_TrampolineCall( \
     300                 :            :         (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL)
     301                 :            : extern PyObject* _PyCFunctionWithKeywords_TrampolineCall(
     302                 :            :     PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *);
     303                 :            : #else
     304                 :            : #define _PyCFunction_TrampolineCall(meth, self, args) \
     305                 :            :     (meth)((self), (args))
     306                 :            : #define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
     307                 :            :     (meth)((self), (args), (kw))
     308                 :            : #endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE
     309                 :            : 
     310                 :            : #ifdef __cplusplus
     311                 :            : }
     312                 :            : #endif
     313                 :            : #endif /* !Py_INTERNAL_OBJECT_H */

Generated by: LCOV version 1.14