summaryrefslogtreecommitdiff
path: root/src/lisp/ao_lisp.h
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-11-15 20:18:59 -0800
committerKeith Packard <keithp@keithp.com>2017-02-20 11:16:51 -0800
commit881161fe1c5fb0e2b1220c30572eb2c45bedbafe (patch)
tree36070649f2e3d46de239f769cc67cc765f3b9c9a /src/lisp/ao_lisp.h
parent994adc7a47cbf3cbf6041eca7430273f8018de08 (diff)
altos/lisp: re-use small frames
This saves a pile more use of the allocator by noting when frames have not been referenced from another frame and freeing them when they go out of scope. Frames with references are left to the allocator to deal with. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/lisp/ao_lisp.h')
-rw-r--r--src/lisp/ao_lisp.h37
1 files changed, 35 insertions, 2 deletions
diff --git a/src/lisp/ao_lisp.h b/src/lisp/ao_lisp.h
index 2db4914f..bcb0a17f 100644
--- a/src/lisp/ao_lisp.h
+++ b/src/lisp/ao_lisp.h
@@ -156,13 +156,33 @@ struct ao_lisp_val {
struct ao_lisp_frame {
uint8_t type;
- uint8_t num;
- ao_poly next;
+ uint8_t _num;
+ ao_poly prev;
struct ao_lisp_val vals[];
};
+#define AO_LISP_FRAME_NUM_MASK 0x7f
+
+/* Set when the frame escapes the lambda */
+#define AO_LISP_FRAME_MARK 0x80
+
+static inline int ao_lisp_frame_num(struct ao_lisp_frame *f) {
+ if (f->_num == 0xff)
+ ao_lisp_abort();
+ return f->_num & AO_LISP_FRAME_NUM_MASK;
+}
+
+static inline int ao_lisp_frame_marked(struct ao_lisp_frame *f) {
+ if (f->_num == 0xff)
+ ao_lisp_abort();
+ return f->_num & AO_LISP_FRAME_MARK;
+}
+
static inline struct ao_lisp_frame *
ao_lisp_poly_frame(ao_poly poly) {
+ struct ao_lisp_frame *frame = ao_lisp_ref(poly);
+ if (frame && frame->_num == 0xff)
+ ao_lisp_abort();
return ao_lisp_ref(poly);
}
@@ -500,6 +520,9 @@ ao_lisp_atom_print(ao_poly a);
struct ao_lisp_atom *
ao_lisp_atom_intern(char *name);
+ao_poly *
+ao_lisp_atom_ref(struct ao_lisp_frame *frame, ao_poly atom);
+
ao_poly
ao_lisp_atom_get(ao_poly atom);
@@ -574,12 +597,22 @@ ao_lisp_read_eval_print(void);
/* frame */
extern const struct ao_lisp_type ao_lisp_frame_type;
+#define AO_LISP_FRAME_FREE 4
+
+extern struct ao_lisp_frame *ao_lisp_frame_free_list[AO_LISP_FRAME_FREE];
+
+ao_poly
+ao_lisp_frame_mark(struct ao_lisp_frame *frame);
+
ao_poly *
ao_lisp_frame_ref(struct ao_lisp_frame *frame, ao_poly atom);
struct ao_lisp_frame *
ao_lisp_frame_new(int num);
+void
+ao_lisp_frame_free(struct ao_lisp_frame *frame);
+
int
ao_lisp_frame_add(struct ao_lisp_frame **frame, ao_poly atom, ao_poly val);