diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-06-14 00:00:37 +0000 |
commit | a73a964e51247ed169d322c725a3a18859f109a3 (patch) | |
tree | 3f752d117274d444bda44e85609aeac1acf313f3 /sys/src/cmd/python/Python/pyarena.c | |
parent | e64efe273fcb921a61bf27d33b230c4e64fcd425 (diff) |
python, hg: tow outside the environment.
they've served us well, and can ride off into the sunset.
Diffstat (limited to 'sys/src/cmd/python/Python/pyarena.c')
-rw-r--r-- | sys/src/cmd/python/Python/pyarena.c | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/sys/src/cmd/python/Python/pyarena.c b/sys/src/cmd/python/Python/pyarena.c deleted file mode 100644 index f4cc474f4..000000000 --- a/sys/src/cmd/python/Python/pyarena.c +++ /dev/null @@ -1,220 +0,0 @@ -#include "Python.h" -#include "pyarena.h" - -/* A simple arena block structure. - - Measurements with standard library modules suggest the average - allocation is about 20 bytes and that most compiles use a single - block. - - TODO(jhylton): Think about a realloc API, maybe just for the last - allocation? -*/ - -#define DEFAULT_BLOCK_SIZE 8192 -#define ALIGNMENT 8 -#define ALIGNMENT_MASK (ALIGNMENT - 1) -#define ROUNDUP(x) (((x) + ALIGNMENT_MASK) & ~ALIGNMENT_MASK) - -typedef struct _block { - /* Total number of bytes owned by this block available to pass out. - * Read-only after initialization. The first such byte starts at - * ab_mem. - */ - size_t ab_size; - - /* Total number of bytes already passed out. The next byte available - * to pass out starts at ab_mem + ab_offset. - */ - size_t ab_offset; - - /* An arena maintains a singly-linked, NULL-terminated list of - * all blocks owned by the arena. These are linked via the - * ab_next member. - */ - struct _block *ab_next; - - /* Pointer to the first allocatable byte owned by this block. Read- - * only after initialization. - */ - void *ab_mem; -} block; - -/* The arena manages two kinds of memory, blocks of raw memory - and a list of PyObject* pointers. PyObjects are decrefed - when the arena is freed. -*/ - -struct _arena { - /* Pointer to the first block allocated for the arena, never NULL. - It is used only to find the first block when the arena is - being freed. - */ - block *a_head; - - /* Pointer to the block currently used for allocation. It's - ab_next field should be NULL. If it is not-null after a - call to block_alloc(), it means a new block has been allocated - and a_cur should be reset to point it. - */ - block *a_cur; - - /* A Python list object containing references to all the PyObject - pointers associated with this area. They will be DECREFed - when the arena is freed. - */ - PyObject *a_objects; - -#if defined(Py_DEBUG) - /* Debug output */ - size_t total_allocs; - size_t total_size; - size_t total_blocks; - size_t total_block_size; - size_t total_big_blocks; -#endif -}; - -static block * -block_new(size_t size) -{ - /* Allocate header and block as one unit. - ab_mem points just past header. */ - block *b = (block *)malloc(sizeof(block) + size); - if (!b) - return NULL; - b->ab_size = size; - b->ab_mem = (void *)(b + 1); - b->ab_next = NULL; - b->ab_offset = ROUNDUP((Py_uintptr_t)(b->ab_mem)) - - (Py_uintptr_t)(b->ab_mem); - return b; -} - -static void -block_free(block *b) { - while (b) { - block *next = b->ab_next; - free(b); - b = next; - } -} - -static void * -block_alloc(block *b, size_t size) -{ - void *p; - assert(b); - size = ROUNDUP(size); - if (b->ab_offset + size > b->ab_size) { - /* If we need to allocate more memory than will fit in - the default block, allocate a one-off block that is - exactly the right size. */ - /* TODO(jhylton): Think about space waste at end of block */ - block *newbl = block_new( - size < DEFAULT_BLOCK_SIZE ? - DEFAULT_BLOCK_SIZE : size); - if (!newbl) - return NULL; - assert(!b->ab_next); - b->ab_next = newbl; - b = newbl; - } - - assert(b->ab_offset + size <= b->ab_size); - p = (void *)(((char *)b->ab_mem) + b->ab_offset); - b->ab_offset += size; - return p; -} - -PyArena * -PyArena_New() -{ - PyArena* arena = (PyArena *)malloc(sizeof(PyArena)); - if (!arena) - return (PyArena*)PyErr_NoMemory(); - - arena->a_head = block_new(DEFAULT_BLOCK_SIZE); - arena->a_cur = arena->a_head; - if (!arena->a_head) { - free((void *)arena); - return (PyArena*)PyErr_NoMemory(); - } - arena->a_objects = PyList_New(0); - if (!arena->a_objects) { - block_free(arena->a_head); - free((void *)arena); - return (PyArena*)PyErr_NoMemory(); - } -#if defined(Py_DEBUG) - arena->total_allocs = 0; - arena->total_size = 0; - arena->total_blocks = 1; - arena->total_block_size = DEFAULT_BLOCK_SIZE; - arena->total_big_blocks = 0; -#endif - return arena; -} - -void -PyArena_Free(PyArena *arena) -{ - int r; - assert(arena); -#if defined(Py_DEBUG) - /* - fprintf(stderr, - "alloc=%d size=%d blocks=%d block_size=%d big=%d objects=%d\n", - arena->total_allocs, arena->total_size, arena->total_blocks, - arena->total_block_size, arena->total_big_blocks, - PyList_Size(arena->a_objects)); - */ -#endif - block_free(arena->a_head); - /* This property normally holds, except when the code being compiled - is sys.getobjects(0), in which case there will be two references. - assert(arena->a_objects->ob_refcnt == 1); - */ - - /* Clear all the elements from the list. This is necessary - to guarantee that they will be DECREFed. */ - r = PyList_SetSlice(arena->a_objects, - 0, PyList_GET_SIZE(arena->a_objects), NULL); - assert(r == 0); - assert(PyList_GET_SIZE(arena->a_objects) == 0); - Py_DECREF(arena->a_objects); - free(arena); -} - -void * -PyArena_Malloc(PyArena *arena, size_t size) -{ - void *p = block_alloc(arena->a_cur, size); - if (!p) - return PyErr_NoMemory(); -#if defined(Py_DEBUG) - arena->total_allocs++; - arena->total_size += size; -#endif - /* Reset cur if we allocated a new block. */ - if (arena->a_cur->ab_next) { - arena->a_cur = arena->a_cur->ab_next; -#if defined(Py_DEBUG) - arena->total_blocks++; - arena->total_block_size += arena->a_cur->ab_size; - if (arena->a_cur->ab_size > DEFAULT_BLOCK_SIZE) - ++arena->total_big_blocks; -#endif - } - return p; -} - -int -PyArena_AddPyObject(PyArena *arena, PyObject *obj) -{ - int r = PyList_Append(arena->a_objects, obj); - if (r >= 0) { - Py_DECREF(obj); - } - return r; -} |