summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Include/cpython/object.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Include/cpython/object.h')
-rw-r--r--contrib/tools/python3/Include/cpython/object.h164
1 files changed, 62 insertions, 102 deletions
diff --git a/contrib/tools/python3/Include/cpython/object.h b/contrib/tools/python3/Include/cpython/object.h
index ae7f780a931..5b3b890dcf3 100644
--- a/contrib/tools/python3/Include/cpython/object.h
+++ b/contrib/tools/python3/Include/cpython/object.h
@@ -4,11 +4,7 @@
PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op);
-
-#ifdef Py_TRACE_REFS
-/* Py_TRACE_REFS is such major surgery that we call external routines. */
-PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
-#endif
+PyAPI_FUNC(void) _Py_ResurrectReference(PyObject *op);
#ifdef Py_REF_DEBUG
/* These are useful as debugging aids when chasing down refleaks. */
@@ -44,6 +40,10 @@ typedef struct _Py_Identifier {
// Index in PyInterpreterState.unicode.ids.array. It is process-wide
// unique and must be initialized to -1.
Py_ssize_t index;
+ // Hidden PyMutex struct for non free-threaded build.
+ struct {
+ uint8_t v;
+ } mutex;
} _Py_Identifier;
#ifndef Py_BUILD_CORE
@@ -56,6 +56,7 @@ typedef struct _Py_Identifier {
#endif /* !Py_BUILD_CORE */
+
typedef struct {
/* Number implementations must check *both*
arguments for proper type and implement the necessary conversions
@@ -220,7 +221,9 @@ struct _typeobject {
PyObject *tp_weaklist; /* not used for static builtin types */
destructor tp_del;
- /* Type attribute cache version tag. Added in version 2.6 */
+ /* Type attribute cache version tag. Added in version 2.6.
+ * If zero, the cache is invalid and must be initialized.
+ */
unsigned int tp_version_tag;
destructor tp_finalize;
@@ -228,10 +231,19 @@ struct _typeobject {
/* bitset of which type-watchers care about this type */
unsigned char tp_watched;
+
+ /* Number of tp_version_tag values used.
+ * Set to _Py_ATTR_CACHE_UNUSED if the attribute cache is
+ * disabled for this type (e.g. due to custom MRO entries).
+ * Otherwise, limited to MAX_VERSIONS_PER_CLASS (defined elsewhere).
+ */
+ uint16_t tp_versions_used;
};
+#define _Py_ATTR_CACHE_UNUSED (30000) // (see tp_versions_used)
+
/* This struct is used by the specializer
- * It should should be treated as an opaque blob
+ * It should be treated as an opaque blob
* by code other than the specializer and interpreter. */
struct _specialization_cache {
// In order to avoid bloating the bytecode with lots of inline caches, the
@@ -246,6 +258,7 @@ struct _specialization_cache {
// *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM):
PyObject *getitem;
uint32_t getitem_version;
+ PyObject *init;
};
/* The *real* layout of a type object when allocated on the heap */
@@ -272,46 +285,21 @@ typedef struct _heaptypeobject {
PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
-PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
-PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *);
-#ifndef Py_BUILD_CORE
-// Backward compatibility for 3rd-party extensions
-// that may be using the old name.
-#define _PyObject_LookupSpecial _PyObject_LookupSpecialId
-#endif
-PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
-PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *);
-PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
-PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *);
+PyAPI_FUNC(PyObject *) _PyType_LookupRef(PyTypeObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
PyAPI_FUNC(void) _Py_BreakPoint(void);
PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
-PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
-
-PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
-PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
-PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *);
-/* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which
- don't raise AttributeError.
- Return 1 and set *result != NULL if an attribute is found.
- Return 0 and set *result == NULL if an attribute is not found;
- an AttributeError is silenced.
- Return -1 and set *result == NULL if an error other than AttributeError
- is raised.
-*/
-PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **);
-PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, _Py_Identifier *, PyObject **);
-
-PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
+PyAPI_FUNC(PyObject*) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
-PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
+PyAPI_FUNC(void) PyUnstable_Object_ClearWeakRefsNoCallbacks(PyObject *);
+
/* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes
dict as the last parameter. */
PyAPI_FUNC(PyObject *)
@@ -387,20 +375,6 @@ PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
#endif
-PyAPI_DATA(PyTypeObject) _PyNone_Type;
-PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type;
-
-/* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
- * Defined in object.c.
- */
-PyAPI_DATA(int) _Py_SwappedOp[];
-
-PyAPI_FUNC(void)
-_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
- size_t sizeof_block);
-PyAPI_FUNC(void)
-_PyObject_DebugTypeStats(FILE *out);
-
/* Define a pair of assertion macros:
_PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
@@ -449,21 +423,6 @@ PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed(
int line,
const char *function);
-/* Check if an object is consistent. For example, ensure that the reference
- counter is greater than or equal to 1, and ensure that ob_type is not NULL.
-
- Call _PyObject_AssertFailed() if the object is inconsistent.
-
- If check_content is zero, only check header fields: reduce the overhead.
-
- The function always return 1. The return value is just here to be able to
- write:
-
- assert(_PyObject_CheckConsistency(obj, 1)); */
-PyAPI_FUNC(int) _PyObject_CheckConsistency(
- PyObject *op,
- int check_content);
-
/* Trashcan mechanism, thanks to Christian Tismer.
@@ -502,8 +461,8 @@ without deallocating anything (and so unbounded call-stack depth is avoided).
When the call stack finishes unwinding again, code generated by the END macro
notices this, and calls another routine to deallocate all the objects that
may have been added to the list of deferred deallocations. In effect, a
-chain of N deallocations is broken into (N-1)/(_PyTrash_UNWIND_LEVEL-1) pieces,
-with the call stack never exceeding a depth of _PyTrash_UNWIND_LEVEL.
+chain of N deallocations is broken into (N-1)/(Py_TRASHCAN_HEADROOM-1) pieces,
+with the call stack never exceeding a depth of Py_TRASHCAN_HEADROOM.
Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base
class, we need to ensure that the trashcan is only triggered on the tp_dealloc
@@ -515,49 +474,40 @@ passed as second argument to Py_TRASHCAN_BEGIN().
/* Python 3.9 private API, invoked by the macros below. */
PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op);
PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate);
+
+PyAPI_FUNC(void) _PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op);
+PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate);
+
+
/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
-PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc);
-#define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \
- do { \
- PyThreadState *_tstate = NULL; \
- /* If "cond" is false, then _tstate remains NULL and the deallocator \
- * is run normally without involving the trashcan */ \
- if (cond) { \
- _tstate = _PyThreadState_UncheckedGet(); \
- if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \
- break; \
- } \
- }
- /* The body of the deallocator is here. */
-#define Py_TRASHCAN_END \
- if (_tstate) { \
- _PyTrash_end(_tstate); \
- } \
- } while (0);
+/* To avoid raising recursion errors during dealloc trigger trashcan before we reach
+ * recursion limit. To avoid trashing, we don't attempt to empty the trashcan until
+ * we have headroom above the trigger limit */
+#define Py_TRASHCAN_HEADROOM 50
#define Py_TRASHCAN_BEGIN(op, dealloc) \
- Py_TRASHCAN_BEGIN_CONDITION((op), \
- _PyTrash_cond(_PyObject_CAST(op), (destructor)(dealloc)))
+do { \
+ PyThreadState *tstate = PyThreadState_Get(); \
+ if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
+ _PyTrash_thread_deposit_object(tstate, (PyObject *)op); \
+ break; \
+ } \
+ tstate->c_recursion_remaining--;
+ /* The body of the deallocator is here. */
+#define Py_TRASHCAN_END \
+ tstate->c_recursion_remaining++; \
+ if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2)) { \
+ _PyTrash_thread_destroy_chain(tstate); \
+ } \
+} while (0);
-/* The following two macros, Py_TRASHCAN_SAFE_BEGIN and
- * Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and
- * will be removed in the future.
- * Use Py_TRASHCAN_BEGIN and Py_TRASHCAN_END instead.
- */
-Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro;
-#define Py_TRASHCAN_SAFE_BEGIN(op) \
- do { \
- UsingDeprecatedTrashcanMacro cond=1; \
- Py_TRASHCAN_BEGIN_CONDITION((op), cond);
-#define Py_TRASHCAN_SAFE_END(op) \
- Py_TRASHCAN_END; \
- } while(0);
PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj);
-PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg);
-PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj);
+PyAPI_FUNC(int) PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg);
+PyAPI_FUNC(int) _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict);
+PyAPI_FUNC(void) PyObject_ClearManagedDict(PyObject *obj);
#define TYPE_MAX_WATCHERS 8
@@ -573,3 +523,13 @@ PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type);
* assigned, or 0 if a new tag could not be assigned.
*/
PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type);
+
+
+typedef enum {
+ PyRefTracer_CREATE = 0,
+ PyRefTracer_DESTROY = 1,
+} PyRefTracerEvent;
+
+typedef int (*PyRefTracer)(PyObject *, PyRefTracerEvent event, void *);
+PyAPI_FUNC(int) PyRefTracer_SetTracer(PyRefTracer tracer, void *data);
+PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**);