Skip to content

Commit

Permalink
Refactor and fix problem on Windows
Browse files Browse the repository at this point in the history
Remove bin allocator and use the SQLite allocator for small
objects as well as large allocations. Create all Paw data structures in
the single heap allocation. Add paw_Options struct for passing options
to Paw.
  • Loading branch information
andy-byers committed Aug 15, 2024
1 parent 2a0845c commit ac649f0
Show file tree
Hide file tree
Showing 41 changed files with 832 additions and 1,378 deletions.
524 changes: 237 additions & 287 deletions src/alloc.c

Large diffs are not rendered by default.

30 changes: 8 additions & 22 deletions src/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@
//
// alloc: Low-level memory allocation routines
//
// Uses 2 different heuristics depending on allocation size. For small allocations,
// we use a slotted allocator that never attempts to merge freelist entries. For
// large allocations we use a slightly-modified version of the memsys3 allocator from
// SQLite (mem3.c). The large object allocator uses only the hash-based partitioning
// scheme, since it expects only large objects.
// Uses code modified from SQLite's memsys3 allocator, which can be found in
// 'src/mem3.c' in the SQLite repository.
//
// TODO: Handle expanding the heap: change paw_Alloc to be more like sbrk, since
// that is all we really need from the user (an initial 'heap' pointer, and a callback
Expand All @@ -23,35 +20,24 @@ struct GcFlag {
uint8_t value;
};

#define FAST_BIN_COUNT 64

struct FastBins {
struct BinInfo *info[FAST_BIN_COUNT];
size_t uninit_size;
size_t arena_size;
void *uninit;
void *arena;
};


struct Heap {
struct FastBins bins;
struct BlockAllocator *a_block;
struct Allocator *a;
uintptr_t bounds[2];
size_t heap_size;
void *heap;
paw_Env *P;

paw_Bool is_owned;

size_t nflags;
uint8_t flags[];
};

#define Z_IN_BOUNDS(H, u) ((H)->bounds[0] <= (u) && (u) < (H)->bounds[1])

int pawZ_init(paw_Env *P, size_t heap_size);
int pawZ_init(paw_Env *P, void *heap, size_t heap_size, paw_Bool is_owned);
void pawZ_uninit(paw_Env *P);

void *pawZ_alloc(paw_Env *P, void *ptr, size_t old_size, size_t new_size);
size_t pawZ_sizeof(void *ptr);
void *pawZ_alloc(paw_Env *P, void *ptr, size_t size);

void pawZ_set_flag(struct Heap *H, uintptr_t ptr);
void pawZ_clear_flag(struct Heap *H, uintptr_t ptr);
Expand Down
39 changes: 24 additions & 15 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@
#include <stdlib.h>
#include <string.h>

#include <gc.h>

static void *default_alloc(void *ud, void *ptr, size_t old_size, size_t new_size)
{
paw_unused(ud);
Expand Down Expand Up @@ -65,21 +63,34 @@ static void open_aux(paw_Env *P, void *arg)
CHECK_GC(P);
}

paw_Env *paw_open(paw_Alloc alloc, void *ud)
#define OR_DEFAULT(a, b) ((a) ? (a) : (b))

paw_Env *paw_open(const struct paw_Options *o)
{
alloc = alloc ? alloc : default_alloc;
paw_Env *P = alloc(ud, NULL, 0, sizeof *P);
if (P == NULL) return NULL;
size_t heap_size = OR_DEFAULT(o->heap_size, PAW_HEAP_DEFAULT);
heap_size &= ~(PAW_ALIGN - 1); // round down
if (heap_size < PAW_HEAP_MIN) return NULL;

void *ud = OR_DEFAULT(o->ud, NULL);
paw_Alloc alloc = OR_DEFAULT(o->alloc, default_alloc);
void *heap = OR_DEFAULT(o->heap, alloc(ud, NULL, 0, heap_size));
const paw_Bool owns_heap = o->heap == NULL;
if (heap == NULL) return NULL;
paw_assert(PAW_IS_ALIGNED(heap));
const size_t zh = heap_size;
void *ph = heap;

paw_Env *P = heap;
*P = (paw_Env){
.alloc = alloc,
.heap_size = heap_size,
.alloc = alloc,
.ud = ud,
};
heap = BUMP_PTR(heap, PAW_ROUND_UP(sizeof(*P)));
heap_size -= PAW_ROUND_UP(sizeof(*P));

// TODO: let user pass in options. These options should work for programs that
// don't use a huge amount of memory.
const size_t heap_size = 8388608 * 2;
if (pawZ_init(P, heap_size)) {
alloc(ud, P, sizeof(*P), 0);
if (pawZ_init(P, heap, heap_size, owns_heap)) {
if (owns_heap) alloc(ud, ph, zh, 0);
return NULL;
}
if (pawC_try(P, open_aux, NULL)) {
Expand All @@ -96,8 +107,6 @@ void paw_close(paw_Env *P)
pawE_uninit(P);
pawS_uninit(P);
pawZ_uninit(P);

P->alloc(P->ud, P, sizeof *P, 0);
}

int paw_find_public(paw_Env *P)
Expand Down Expand Up @@ -319,7 +328,7 @@ int paw_call(paw_Env *P, int argc)

int paw_get_count(paw_Env *P)
{
return P->top.p - P->cf->base.p;
return CAST(P->top.p - P->cf->base.p, int);
}

static int upvalue_index(int nup, int index)
Expand Down
2 changes: 1 addition & 1 deletion src/ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void pawAst_free(struct Ast *ast)
struct T *pawAst_new_##name(struct Ast *ast, enum T##Kind kind) \
{ \
struct T *r = pawK_pool_alloc(ENV(ast), &(ast)->pool, sizeof(struct T)); \
r->hdr.line = (ast)->lex->line; \
r->hdr.line = (ast)->lex->last_line; \
r->hdr.kind = kind; \
return r; \
}
Expand Down
2 changes: 1 addition & 1 deletion src/auxlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void pawL_add_value(paw_Env *P, Buffer *buf, paw_Type type)
// Table and stringify algorithm modified from micropython
static const uint8_t kLogBase2[] = {
0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, //
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5,
};

size_t pawL_integer_format_size(size_t nbits, int base)
Expand Down
2 changes: 1 addition & 1 deletion src/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void pawC_stack_grow(paw_Env *P, int n)
{
paw_assert(n > 0);
paw_assert(P->bound.p >= P->stack.p);
const int alloc = CAST_SIZE(P->bound.p - P->stack.p);
const int alloc = CAST(P->bound.p - P->stack.p, int);
pawC_stack_realloc(P, NEXT_ALLOC(alloc, n));
}

Expand Down
2 changes: 1 addition & 1 deletion src/code.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static void add_line(struct FuncState *fs)
}
pawM_grow(P, p->lines, fs->nlines, p->nlines);
p->lines[fs->nlines++] = (struct LineInfo){
.line = -1, // TODO: Get line from somewhere...
.line = fs->line,
.pc = fs->pc,
};
}
Expand Down
Loading

0 comments on commit ac649f0

Please sign in to comment.