summaryrefslogtreecommitdiff
path: root/src/lisp/ao_lisp_mem.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-11-01 21:14:45 -0700
committerKeith Packard <keithp@keithp.com>2016-11-17 22:18:39 -0800
commit338723847e66f7c34a6b5e54d094ed52dc5665c3 (patch)
treec53d501a9e5f29d84c8c4ab65d7198b0e5e14b12 /src/lisp/ao_lisp_mem.c
parent75f07353a4fad170ac1cc6af98ed1aad7d1c0c88 (diff)
altos/lisp: Change lisp objects to use ao_poly everywhere. Add const
This makes all lisp objects use 16-bit ints for references so we can hold more stuff in small amounts of memory. Also adds a separate constant pool of lisp objects for builtins, initial atoms and constant lisp code. Now builds (and runs!) on the nucleo-32 boards. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp_mem.c')
-rw-r--r--src/lisp/ao_lisp_mem.c41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/lisp/ao_lisp_mem.c b/src/lisp/ao_lisp_mem.c
index d008519b..7295d150 100644
--- a/src/lisp/ao_lisp_mem.c
+++ b/src/lisp/ao_lisp_mem.c
@@ -12,23 +12,34 @@
* General Public License for more details.
*/
+#define AO_LISP_CONST_BITS
+
#include "ao_lisp.h"
#include <stdio.h>
-uint8_t ao_lisp_pool[AO_LISP_POOL];
+uint8_t ao_lisp_pool[AO_LISP_POOL] __attribute__((aligned(4)));
+
+#ifdef AO_LISP_MAKE_CONST
+#include <stdlib.h>
+uint8_t ao_lisp_const[AO_LISP_POOL_CONST] __attribute__((aligned(4)));
+#endif
+
+uint8_t ao_lisp_exception;
struct ao_lisp_root {
void **addr;
- const struct ao_lisp_mem_type *type;
+ const struct ao_lisp_type *type;
};
+#define AO_LISP_ROOT 16
+
static struct ao_lisp_root ao_lisp_root[AO_LISP_ROOT];
static uint8_t ao_lisp_busy[AO_LISP_POOL / 32];
static uint8_t ao_lisp_moving[AO_LISP_POOL / 32];
-static uint16_t ao_lisp_top;
+uint16_t ao_lisp_top;
static inline void mark(uint8_t *tag, int offset) {
int byte = offset >> 5;
@@ -59,9 +70,13 @@ static int
mark_object(uint8_t *tag, void *addr, int size) {
int base;
int bound;
+
if (!addr)
return 1;
+ if ((uint8_t *) addr < ao_lisp_pool || ao_lisp_pool + AO_LISP_POOL <= (uint8_t*) addr)
+ return 1;
+
base = (uint8_t *) addr - ao_lisp_pool;
bound = base + size;
@@ -150,7 +165,7 @@ collect(void)
void
-ao_lisp_mark(const struct ao_lisp_mem_type *type, void *addr)
+ao_lisp_mark(const struct ao_lisp_type *type, void *addr)
{
if (mark_object(ao_lisp_busy, addr, type->size(addr)))
return;
@@ -175,7 +190,7 @@ check_move(void *addr, int size)
}
void *
-ao_lisp_move(const struct ao_lisp_mem_type *type, void *addr)
+ao_lisp_move(const struct ao_lisp_type *type, void *addr)
{
int size = type->size(addr);
@@ -206,19 +221,29 @@ ao_lisp_alloc(int size)
{
void *addr;
- size = (size + 3) & ~3;
+ size = ao_lisp_mem_round(size);
+#ifdef AO_LISP_MAKE_CONST
+ if (ao_lisp_top + size > AO_LISP_POOL_CONST) {
+ fprintf(stderr, "Too much constant data, increase AO_LISP_POOL_CONST\n");
+ exit(1);
+ }
+ addr = ao_lisp_const + ao_lisp_top;
+#else
if (ao_lisp_top + size > AO_LISP_POOL) {
collect();
- if (ao_lisp_top + size > AO_LISP_POOL)
+ if (ao_lisp_top + size > AO_LISP_POOL) {
+ ao_lisp_exception |= AO_LISP_OOM;
return NULL;
+ }
}
addr = ao_lisp_pool + ao_lisp_top;
+#endif
ao_lisp_top += size;
return addr;
}
int
-ao_lisp_root_add(const struct ao_lisp_mem_type *type, void *addr)
+ao_lisp_root_add(const struct ao_lisp_type *type, void *addr)
{
int i;
for (i = 0; i < AO_LISP_ROOT; i++) {