python 2.7 -> python 3.14
This commit is contained in:
145
extern/include/python/internal/pycore_pymem.h
vendored
Normal file
145
extern/include/python/internal/pycore_pymem.h
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
#ifndef Py_INTERNAL_PYMEM_H
|
||||
#define Py_INTERNAL_PYMEM_H
|
||||
|
||||
#include "pycore_llist.h" // struct llist_node
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef Py_BUILD_CORE
|
||||
# error "this header requires Py_BUILD_CORE define"
|
||||
#endif
|
||||
|
||||
// Try to get the allocators name set by _PyMem_SetupAllocators().
|
||||
// Return NULL if unknown.
|
||||
// Export for '_testinternalcapi' shared extension.
|
||||
PyAPI_FUNC(const char*) _PyMem_GetCurrentAllocatorName(void);
|
||||
|
||||
// strdup() using PyMem_RawMalloc()
|
||||
extern char* _PyMem_RawStrdup(const char *str);
|
||||
|
||||
// strdup() using PyMem_Malloc().
|
||||
// Export for '_pickle ' shared extension.
|
||||
PyAPI_FUNC(char*) _PyMem_Strdup(const char *str);
|
||||
|
||||
// wcsdup() using PyMem_RawMalloc()
|
||||
extern wchar_t* _PyMem_RawWcsdup(const wchar_t *str);
|
||||
|
||||
/* Special bytes broadcast into debug memory blocks at appropriate times.
|
||||
Strings of these are unlikely to be valid addresses, floats, ints or
|
||||
7-bit ASCII.
|
||||
|
||||
- PYMEM_CLEANBYTE: clean (newly allocated) memory
|
||||
- PYMEM_DEADBYTE dead (newly freed) memory
|
||||
- PYMEM_FORBIDDENBYTE: untouchable bytes at each end of a block
|
||||
|
||||
Byte patterns 0xCB, 0xDB and 0xFB have been replaced with 0xCD, 0xDD and
|
||||
0xFD to use the same values as Windows CRT debug malloc() and free().
|
||||
If modified, _PyMem_IsPtrFreed() should be updated as well. */
|
||||
#define PYMEM_CLEANBYTE 0xCD
|
||||
#define PYMEM_DEADBYTE 0xDD
|
||||
#define PYMEM_FORBIDDENBYTE 0xFD
|
||||
|
||||
/* Heuristic checking if a pointer value is newly allocated
|
||||
(uninitialized), newly freed or NULL (is equal to zero).
|
||||
|
||||
The pointer is not dereferenced, only the pointer value is checked.
|
||||
|
||||
The heuristic relies on the debug hooks on Python memory allocators which
|
||||
fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory
|
||||
with DEADBYTE (0xDD). Detect also "untouchable bytes" marked
|
||||
with FORBIDDENBYTE (0xFD). */
|
||||
static inline int _PyMem_IsPtrFreed(const void *ptr)
|
||||
{
|
||||
uintptr_t value = (uintptr_t)ptr;
|
||||
#if SIZEOF_VOID_P == 8
|
||||
return (value <= 0xff // NULL, 0x1, 0x2, ..., 0xff
|
||||
|| value == (uintptr_t)0xCDCDCDCDCDCDCDCD
|
||||
|| value == (uintptr_t)0xDDDDDDDDDDDDDDDD
|
||||
|| value == (uintptr_t)0xFDFDFDFDFDFDFDFD
|
||||
|| value >= (uintptr_t)0xFFFFFFFFFFFFFF00); // -0xff, ..., -2, -1
|
||||
#elif SIZEOF_VOID_P == 4
|
||||
return (value <= 0xff
|
||||
|| value == (uintptr_t)0xCDCDCDCD
|
||||
|| value == (uintptr_t)0xDDDDDDDD
|
||||
|| value == (uintptr_t)0xFDFDFDFD
|
||||
|| value >= (uintptr_t)0xFFFFFF00);
|
||||
#else
|
||||
# error "unknown pointer size"
|
||||
#endif
|
||||
}
|
||||
|
||||
// Similar to _PyMem_IsPtrFreed() but expects an 'unsigned long' instead of a
|
||||
// pointer.
|
||||
static inline int _PyMem_IsULongFreed(unsigned long value)
|
||||
{
|
||||
#if SIZEOF_LONG == 8
|
||||
return (value == 0
|
||||
|| value == (unsigned long)0xCDCDCDCDCDCDCDCD
|
||||
|| value == (unsigned long)0xDDDDDDDDDDDDDDDD
|
||||
|| value == (unsigned long)0xFDFDFDFDFDFDFDFD
|
||||
|| value == (unsigned long)0xFFFFFFFFFFFFFFFF);
|
||||
#elif SIZEOF_LONG == 4
|
||||
return (value == 0
|
||||
|| value == (unsigned long)0xCDCDCDCD
|
||||
|| value == (unsigned long)0xDDDDDDDD
|
||||
|| value == (unsigned long)0xFDFDFDFD
|
||||
|| value == (unsigned long)0xFFFFFFFF);
|
||||
#else
|
||||
# error "unknown long size"
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int _PyMem_GetAllocatorName(
|
||||
const char *name,
|
||||
PyMemAllocatorName *allocator);
|
||||
|
||||
/* Configure the Python memory allocators.
|
||||
Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators.
|
||||
PYMEM_ALLOCATOR_NOT_SET does nothing. */
|
||||
extern int _PyMem_SetupAllocators(PyMemAllocatorName allocator);
|
||||
|
||||
// Default raw memory allocator that is not affected by PyMem_SetAllocator()
|
||||
extern void *_PyMem_DefaultRawMalloc(size_t);
|
||||
extern void *_PyMem_DefaultRawCalloc(size_t, size_t);
|
||||
extern void *_PyMem_DefaultRawRealloc(void *, size_t);
|
||||
extern void _PyMem_DefaultRawFree(void *);
|
||||
extern wchar_t *_PyMem_DefaultRawWcsdup(const wchar_t *str);
|
||||
|
||||
/* Is the debug allocator enabled? */
|
||||
extern int _PyMem_DebugEnabled(void);
|
||||
|
||||
// Enqueue a pointer to be freed possibly after some delay.
|
||||
extern void _PyMem_FreeDelayed(void *ptr, size_t size);
|
||||
|
||||
// Enqueue an object to be freed possibly after some delay
|
||||
#ifdef Py_GIL_DISABLED
|
||||
PyAPI_FUNC(void) _PyObject_XDecRefDelayed(PyObject *obj);
|
||||
#else
|
||||
static inline void _PyObject_XDecRefDelayed(PyObject *obj)
|
||||
{
|
||||
Py_XDECREF(obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Periodically process delayed free requests.
|
||||
extern void _PyMem_ProcessDelayed(PyThreadState *tstate);
|
||||
|
||||
// Periodically process delayed free requests when the world is stopped.
|
||||
// Notify of any objects whic should be freeed.
|
||||
typedef void (*delayed_dealloc_cb)(PyObject *, void *);
|
||||
extern void _PyMem_ProcessDelayedNoDealloc(PyThreadState *tstate,
|
||||
delayed_dealloc_cb cb, void *state);
|
||||
|
||||
// Abandon all thread-local delayed free requests and push them to the
|
||||
// interpreter's queue.
|
||||
extern void _PyMem_AbandonDelayed(PyThreadState *tstate);
|
||||
|
||||
// On interpreter shutdown, frees all delayed free requests.
|
||||
extern void _PyMem_FiniDelayed(PyInterpreterState *interp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // !Py_INTERNAL_PYMEM_H
|
||||
Reference in New Issue
Block a user