mirror of
https://github.com/python/cpython.git
synced 2025-08-30 05:35:08 +00:00
Tabify
This commit is contained in:
parent
14ca327f99
commit
08533fdad6
1 changed files with 85 additions and 82 deletions
167
Python/pyarena.c
167
Python/pyarena.c
|
@ -4,8 +4,8 @@
|
||||||
/* An arena list is a linked list that can store PyObjects. */
|
/* An arena list is a linked list that can store PyObjects. */
|
||||||
|
|
||||||
typedef struct _arena_list {
|
typedef struct _arena_list {
|
||||||
struct _arena_list *al_next;
|
struct _arena_list *al_next;
|
||||||
void *al_pointer;
|
void *al_pointer;
|
||||||
} PyArenaList;
|
} PyArenaList;
|
||||||
|
|
||||||
/* A simple arena block structure */
|
/* A simple arena block structure */
|
||||||
|
@ -13,134 +13,137 @@ typedef struct _arena_list {
|
||||||
|
|
||||||
#define DEFAULT_BLOCK_SIZE 8192
|
#define DEFAULT_BLOCK_SIZE 8192
|
||||||
typedef struct _block {
|
typedef struct _block {
|
||||||
size_t ab_size;
|
size_t ab_size;
|
||||||
size_t ab_offset;
|
size_t ab_offset;
|
||||||
struct _block *ab_next;
|
struct _block *ab_next;
|
||||||
void *ab_mem;
|
void *ab_mem;
|
||||||
} block;
|
} block;
|
||||||
|
|
||||||
struct _arena {
|
struct _arena {
|
||||||
block *a_head;
|
block *a_head;
|
||||||
block *a_cur;
|
block *a_cur;
|
||||||
PyArenaList *a_object_head;
|
PyArenaList *a_object_head;
|
||||||
PyArenaList *a_object_tail;
|
PyArenaList *a_object_tail;
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyArenaList*
|
static PyArenaList*
|
||||||
PyArenaList_New(void)
|
PyArenaList_New(void)
|
||||||
{
|
{
|
||||||
PyArenaList *alist = (PyArenaList *)malloc(sizeof(PyArenaList));
|
PyArenaList *alist = (PyArenaList *)malloc(sizeof(PyArenaList));
|
||||||
if (!alist)
|
if (!alist)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
alist->al_next = NULL;
|
alist->al_next = NULL;
|
||||||
alist->al_pointer = NULL;
|
alist->al_pointer = NULL;
|
||||||
return alist;
|
return alist;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
PyArenaList_FreeObject(PyArenaList *alist)
|
PyArenaList_FreeObject(PyArenaList *alist)
|
||||||
{
|
{
|
||||||
while (alist) {
|
while (alist) {
|
||||||
PyArenaList *prev;
|
PyArenaList *prev;
|
||||||
Py_XDECREF((PyObject *)alist->al_pointer);
|
Py_XDECREF((PyObject *)alist->al_pointer);
|
||||||
alist->al_pointer = NULL;
|
alist->al_pointer = NULL;
|
||||||
prev = alist;
|
prev = alist;
|
||||||
alist = alist->al_next;
|
alist = alist->al_next;
|
||||||
free(prev);
|
free(prev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static block *
|
static block *
|
||||||
block_new(size_t size)
|
block_new(size_t size)
|
||||||
{
|
{
|
||||||
/* Allocate header and block as one unit. ab_mem points just past header. */
|
/* Allocate header and block as one unit.
|
||||||
block *b = (block *)malloc(sizeof(block) + size);
|
ab_mem points just past header. */
|
||||||
if (!b)
|
block *b = (block *)malloc(sizeof(block) + size);
|
||||||
return NULL;
|
if (!b)
|
||||||
b->ab_size = size;
|
return NULL;
|
||||||
b->ab_mem = (void *)(b + 1);
|
b->ab_size = size;
|
||||||
b->ab_next = NULL;
|
b->ab_mem = (void *)(b + 1);
|
||||||
b->ab_offset = 0;
|
b->ab_next = NULL;
|
||||||
return b;
|
b->ab_offset = 0;
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
block_free(block *b) {
|
block_free(block *b) {
|
||||||
while (b) {
|
while (b) {
|
||||||
block *next = b->ab_next;
|
block *next = b->ab_next;
|
||||||
free(b);
|
free(b);
|
||||||
b = next;
|
b = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
block_alloc(block *b, size_t size)
|
block_alloc(block *b, size_t size)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
assert(b);
|
assert(b);
|
||||||
if (b->ab_offset + size > b->ab_size) {
|
if (b->ab_offset + size > b->ab_size) {
|
||||||
/* If we need to allocate more memory than will fit in the default
|
/* If we need to allocate more memory than will fit in
|
||||||
block, allocate a one-off block that is exactly the right size. */
|
the default block, allocate a one-off block that is
|
||||||
/* TODO(jhylton): Think more about space waste at end of block */
|
exactly the right size. */
|
||||||
block *new = block_new(
|
/* TODO(jhylton): Think about space waste at end of block */
|
||||||
size < DEFAULT_BLOCK_SIZE ? DEFAULT_BLOCK_SIZE : size);
|
block *new = block_new(
|
||||||
if (!new)
|
size < DEFAULT_BLOCK_SIZE ?
|
||||||
return NULL;
|
DEFAULT_BLOCK_SIZE : size);
|
||||||
assert(!b->ab_next);
|
if (!new)
|
||||||
b->ab_next = new;
|
return NULL;
|
||||||
b = new;
|
assert(!b->ab_next);
|
||||||
}
|
b->ab_next = new;
|
||||||
|
b = new;
|
||||||
|
}
|
||||||
|
|
||||||
assert(b->ab_offset + size <= b->ab_size);
|
assert(b->ab_offset + size <= b->ab_size);
|
||||||
p = (void *)(((char *)b->ab_mem) + b->ab_offset);
|
p = (void *)(((char *)b->ab_mem) + b->ab_offset);
|
||||||
b->ab_offset += size;
|
b->ab_offset += size;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyArena *
|
PyArena *
|
||||||
PyArena_New()
|
PyArena_New()
|
||||||
{
|
{
|
||||||
PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
|
PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
|
||||||
if (!arena)
|
if (!arena)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
|
arena->a_head = block_new(DEFAULT_BLOCK_SIZE);
|
||||||
arena->a_cur = arena->a_head;
|
arena->a_cur = arena->a_head;
|
||||||
arena->a_object_head = PyArenaList_New();
|
arena->a_object_head = PyArenaList_New();
|
||||||
arena->a_object_tail = arena->a_object_head;
|
arena->a_object_tail = arena->a_object_head;
|
||||||
return arena;
|
return arena;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PyArena_Free(PyArena *arena)
|
PyArena_Free(PyArena *arena)
|
||||||
{
|
{
|
||||||
assert(arena);
|
assert(arena);
|
||||||
block_free(arena->a_head);
|
block_free(arena->a_head);
|
||||||
PyArenaList_FreeObject(arena->a_object_head);
|
PyArenaList_FreeObject(arena->a_object_head);
|
||||||
free(arena);
|
free(arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
PyArena_Malloc(PyArena *arena, size_t size)
|
PyArena_Malloc(PyArena *arena, size_t size)
|
||||||
{
|
{
|
||||||
void *p = block_alloc(arena->a_cur, size);
|
void *p = block_alloc(arena->a_cur, size);
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* Reset cur if we allocated a new block. */
|
/* Reset cur if we allocated a new block. */
|
||||||
if (arena->a_cur->ab_next) {
|
if (arena->a_cur->ab_next) {
|
||||||
arena->a_cur = arena->a_cur->ab_next;
|
arena->a_cur = arena->a_cur->ab_next;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
PyArena_AddPyObject(PyArena *arena, PyObject *pointer)
|
PyArena_AddPyObject(PyArena *arena, PyObject *pointer)
|
||||||
{
|
{
|
||||||
PyArenaList *tail = arena->a_object_tail;
|
PyArenaList *tail = arena->a_object_tail;
|
||||||
assert(pointer);
|
assert(pointer);
|
||||||
tail->al_next = PyArenaList_New();
|
tail->al_next = PyArenaList_New();
|
||||||
tail->al_pointer = pointer;
|
tail->al_pointer = pointer;
|
||||||
arena->a_object_tail = tail->al_next;
|
arena->a_object_tail = tail->al_next;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue