Compare commits
4 Commits
edce319957
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d88523d39f | ||
|
|
13f3de726b | ||
|
|
8231cf4e14 | ||
|
|
55ed8c5939 |
@@ -15,10 +15,14 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
u64 padding : 56;
|
||||||
|
tag_t tag : 8;
|
||||||
u64 references;
|
u64 references;
|
||||||
tag_t tag : 8;
|
|
||||||
} alloc_metadata_t;
|
} alloc_metadata_t;
|
||||||
|
|
||||||
|
static_assert(sizeof(alloc_metadata_t) == 16,
|
||||||
|
"16 byte metadata required for alignment purposes");
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
alloc_metadata_t metadata;
|
alloc_metadata_t metadata;
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ typedef enum Tag
|
|||||||
#define INT_MIN (-(INT_MAX + 1))
|
#define INT_MIN (-(INT_MAX + 1))
|
||||||
|
|
||||||
tag_t tag_get(const lisp_t *);
|
tag_t tag_get(const lisp_t *);
|
||||||
|
u64 tag_sizeof(tag_t);
|
||||||
|
u64 lisp_sizeof(lisp_t *);
|
||||||
|
lisp_t *lisp_reset(lisp_t *);
|
||||||
|
void lisp_print(FILE *, lisp_t *);
|
||||||
|
|
||||||
lisp_t *tag_smi(const i64);
|
lisp_t *tag_smi(const i64);
|
||||||
lisp_t *tag_sym(const char *);
|
lisp_t *tag_sym(const char *);
|
||||||
lisp_t *tag_cons(const cons_t *);
|
lisp_t *tag_cons(const cons_t *);
|
||||||
@@ -65,10 +70,6 @@ str_t *as_str(lisp_t *);
|
|||||||
#define CAR(L) (as_cons(L)->car)
|
#define CAR(L) (as_cons(L)->car)
|
||||||
#define CDR(L) (as_cons(L)->cdr)
|
#define CDR(L) (as_cons(L)->cdr)
|
||||||
|
|
||||||
void lisp_print(FILE *, lisp_t *);
|
|
||||||
u64 tag_sizeof(tag_t);
|
|
||||||
u64 lisp_sizeof(lisp_t *);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copyright (C) 2026 Aryadev Chavali
|
/* Copyright (C) 2026 Aryadev Chavali
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ typedef struct
|
|||||||
|
|
||||||
void sys_init(sys_t *);
|
void sys_init(sys_t *);
|
||||||
lisp_t *sys_alloc(sys_t *, tag_t type);
|
lisp_t *sys_alloc(sys_t *, tag_t type);
|
||||||
|
void sys_delete(sys_t *, lisp_t *);
|
||||||
void sys_free(sys_t *);
|
void sys_free(sys_t *);
|
||||||
|
|
||||||
// Debugging function: provides total memory usage from system.
|
// Debugging function: provides total memory usage from system.
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ static_assert(sizeof(vec_t) == 64, "vec_t has to be 64 bytes as part of SBO");
|
|||||||
|
|
||||||
void vec_init(vec_t *, u64);
|
void vec_init(vec_t *, u64);
|
||||||
void vec_free(vec_t *);
|
void vec_free(vec_t *);
|
||||||
|
void vec_reset(vec_t *);
|
||||||
u8 *vec_data(vec_t *);
|
u8 *vec_data(vec_t *);
|
||||||
|
|
||||||
// Append, possibly reallocating memory
|
// Append, possibly reallocating memory
|
||||||
|
|||||||
@@ -158,8 +158,35 @@ end:
|
|||||||
|
|
||||||
void alloc_delete(alloc_t *alloc, lisp_t *lisp)
|
void alloc_delete(alloc_t *alloc, lisp_t *lisp)
|
||||||
{
|
{
|
||||||
|
switch (tag_get(lisp))
|
||||||
|
{
|
||||||
|
case TAG_CONS:
|
||||||
|
case TAG_VEC:
|
||||||
|
case TAG_STR:
|
||||||
|
break;
|
||||||
|
case TAG_NIL: // These can't be deleted (not allocated)
|
||||||
|
case TAG_SMI:
|
||||||
|
case TAG_SYM:
|
||||||
|
default:
|
||||||
|
FAIL("Unreachable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
alloc_node_t *node = lisp_to_node(lisp);
|
alloc_node_t *node = lisp_to_node(lisp);
|
||||||
assert(node && node->metadata.references == 0);
|
assert(node && node->metadata.references == 0);
|
||||||
|
|
||||||
|
// If already present in the free vector, stop.
|
||||||
|
FOR_VEC(i, &alloc->free_vec, alloc_node_t *)
|
||||||
|
{
|
||||||
|
alloc_node_t *other = VEC_GET(&alloc->pages, i, alloc_node_t *);
|
||||||
|
if (other == node)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, add to the free vector.
|
||||||
|
lisp_reset(lisp);
|
||||||
vec_append(&alloc->free_vec, &node, sizeof(node));
|
vec_append(&alloc->free_vec, &node, sizeof(node));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,7 +206,7 @@ void alloc_free(alloc_t *alloc)
|
|||||||
FOR_VEC(i, &alloc->pages, page_t *)
|
FOR_VEC(i, &alloc->pages, page_t *)
|
||||||
{
|
{
|
||||||
page_t *page = VEC_GET(&alloc->pages, i, page_t *);
|
page_t *page = VEC_GET(&alloc->pages, i, page_t *);
|
||||||
// Iterate through every alloc_node in this page
|
// Iterate through every alloc_node in this page (dynamic walk)
|
||||||
for (u64 j = 0; j < VEC_SIZE(&page->data, u8);)
|
for (u64 j = 0; j < VEC_SIZE(&page->data, u8);)
|
||||||
{
|
{
|
||||||
alloc_node_t *node = (alloc_node_t *)(vec_data(&page->data) + j);
|
alloc_node_t *node = (alloc_node_t *)(vec_data(&page->data) + j);
|
||||||
|
|||||||
34
src/lisp.c
34
src/lisp.c
@@ -238,6 +238,40 @@ u64 lisp_sizeof(lisp_t *lisp)
|
|||||||
return tag_sizeof(tag_get(lisp));
|
return tag_sizeof(tag_get(lisp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lisp_t *lisp_reset(lisp_t *lisp)
|
||||||
|
{
|
||||||
|
switch (tag_get(lisp))
|
||||||
|
{
|
||||||
|
case TAG_NIL:
|
||||||
|
case TAG_SMI:
|
||||||
|
case TAG_SYM:
|
||||||
|
// Nothing to "reset" here.
|
||||||
|
return lisp;
|
||||||
|
case TAG_CONS:
|
||||||
|
{
|
||||||
|
// Make `car` and `cons` NIL
|
||||||
|
CAR(lisp) = NIL;
|
||||||
|
CDR(lisp) = NIL;
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
case TAG_VEC:
|
||||||
|
{
|
||||||
|
vec_reset(as_vec(lisp));
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
case TAG_STR:
|
||||||
|
{
|
||||||
|
vec_reset(&as_str(lisp)->data);
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
FAIL("Unreachable");
|
||||||
|
return lisp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Copyright (C) 2025, 2026 Aryadev Chavali
|
/* Copyright (C) 2025, 2026 Aryadev Chavali
|
||||||
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ lisp_t *sys_alloc(sys_t *sys, tag_t type)
|
|||||||
return NIL;
|
return NIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sys_delete(sys_t *sys, lisp_t *lisp)
|
||||||
|
{
|
||||||
|
alloc_delete(&sys->memory, lisp);
|
||||||
|
}
|
||||||
|
|
||||||
u64 sys_cost(sys_t *sys)
|
u64 sys_cost(sys_t *sys)
|
||||||
{
|
{
|
||||||
return alloc_cost(&sys->memory) + sym_table_cost(&sys->symtable);
|
return alloc_cost(&sys->memory) + sym_table_cost(&sys->symtable);
|
||||||
|
|||||||
@@ -38,6 +38,14 @@ void vec_free(vec_t *vec)
|
|||||||
memset(vec, 0, sizeof(*vec));
|
memset(vec, 0, sizeof(*vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vec_reset(vec_t *vec)
|
||||||
|
{
|
||||||
|
if (!vec)
|
||||||
|
return;
|
||||||
|
memset(vec_data(vec), 0, vec->capacity);
|
||||||
|
vec->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
u8 *vec_data(vec_t *vec)
|
u8 *vec_data(vec_t *vec)
|
||||||
{
|
{
|
||||||
return vec->not_inlined ? vec->ptr : vec->inlined;
|
return vec->not_inlined ? vec->ptr : vec->inlined;
|
||||||
|
|||||||
Reference in New Issue
Block a user