LispBM
heap.h
Go to the documentation of this file.
1 
2 /*
3  Copyright 2018 , 2022 Joel Svensson svenssonjoel@yahoo.se
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
20 #ifndef HEAP_H_
21 #define HEAP_H_
22 
23 #include <string.h>
24 #include <stdarg.h>
25 
26 #include "lbm_types.h"
27 #include "symrepr.h"
28 #include "stack.h"
29 #include "lbm_memory.h"
30 #include "lbm_defines.h"
31 #include "lbm_channel.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /*
38 Planning for a more space efficient heap representation.
39 TODO: Need to find a good reference to read up on this.
40  - List based heap
41  - Easy to implement and somewhat efficient
42 
43 0000 0000 Size Free bits
44 003F FFFF 4MB 10
45 007F FFFF 8MB 9
46 00FF FFFF 16MB 8
47 01FF FFFF 32MB 7
48 03FF FFFF 64MB 6 * Kind of heap size I am looking for
49 07FF FFFF 128MB 5
50 0FFF FFFF 256MB 4
51 1FFF FFFF 512MB 3
52 
53 
54 --- May 9 2021 ---
55 Actually now I am much more interested in way smaller memories ;)
56 
57 0000 0000 Size Free bits
58 0000 0FFF 4KB 20 |
59 0000 1FFF 8KB 19 |
60 0000 3FFF 16KB 18 |
61 0000 7FFF 32KB 17 |
62 0000 FFFF 64KB 16 |
63 0001 FFFF 128KB 15 |
64 0003 FFFF 256KB 14 | - This range is very interesting.
65 0007 FFFF 512KB 13
66 000F FFFF 1MB 12
67 001F FFFF 2MB 11
68 003F FFFF 4MB 10
69 007F FFFF 8MB 9
70 00FF FFFF 16MB 8
71 01FF FFFF 32MB 7
72 03FF FFFF 64MB 6
73 07FF FFFF 128MB 5
74 0FFF FFFF 256MB 4
75 1FFF FFFF 512MB 3
76 
77 Those are the kind of platforms that are fun... so a bunch of
78 wasted bits in heap pointers if we run on small MCUs.
79 
80 -----------------
81 
82 it is also the case that not all addresses will be used if all "cells" are
83 of the same size, 8 bytes...
84 
85 value 0: 0000 0000
86 value 1: 0000 0008
87 value 3: 0000 0010
88 value 4: 0000 0018
89 
90 Means bits 0,1,2 will always be empty in a valid address.
91 
92 Cons cells also need to be have room for 2 pointers. So each ted cell from
93 memory should be 8bytes.
94 
95 Things that needs to be represented within these bits:
96 
97  - GC MARK one per cell
98  - TYPE: type of CAR and type of cons
99 
100 Types I would want:
101  - Full 32bit integer. Does not leave room for identification of type
102  - Float values. Same problem
103 
104 
105 Free bits in pointers 64MB heap:
106 31 30 29 28 27 26 2 1 0
107 0 0 0 0 0 0 XX XXXX XXXX XXXX XXXX XXXX X 0 0 0
108 
109 
110 Information needed for each cell:
111  Meaning | bits total | bits per car | bits per cdr
112  GC mark | 2 | 1 | 1 - only one of them will be used (the other is wasted)
113  Type | 2x | x | x
114  Ptr/!ptr | 2 | 1 | 1
115 
116 
117 Types (unboxed):
118  - Symbols
119  - 28bit integer ( will need signed shift right functionality )
120  - 28bit unsigned integer
121  - Character
122 
123 If four types is all that should be possible (unboxed). then 2 bits are needed to differentiate.
124 2 + 1 + 1 = 4 => 28bits for data.
125 
126 bit 0: ptr/!ptr
127 bit 1: gc
128 bit 2-3: type (if not ptr)
129 bit 3 - 24 ptr (if ptr)
130 bit 4 - 31 value (if value)
131 
132 An unboxed value can occupy a car or cdr field in a cons cell.
133 
134 types (boxed) extra information in pointer to cell can contain information
135  - 32 bit integer
136  - 32 bit unsigned integer
137  - 32 bit float
138 
139 boxed representation:
140  [ptr| cdr]
141  |
142  [Value | Aux + GC_MARK]
143 
144 Kinds of pointers:
145  - Pointer to cons cell.
146  - Pointer to unboxed value (fixnums not in a list, I hope this is so rare that it can be removed )
147  - integer
148  - unsigned integer
149  - symbol
150  - float
151  - Pointer to boxed value.
152  - 32 bit integer
153  - 32 bit unsigned integer
154  - 32 bit float
155  - (Maybe something else ? Vectors/strings allocated in memory not occupied by heap?)
156  - vector of int
157  - vector of uint
158  - vector of float
159  - vector of double
160  - String
161 
162 13 pointer"types" -> needs 4 bits
163 for 64MB heap there are 6 free bits. So with this scheme going to 128MB or 256MB heap
164 is also possible
165 
166  a pointer to some off heap vector/string could be represented by
167 
168  [ptr | cdr]
169  |
170  [full pointer | Aux + GC_MARK]
171  |
172  [VECTOR]
173 
174 Aux bits could be used for storing vector size. Up to 30bits should be available there
175 >> This is problematic. Now the information that something is a vector is split up
176 >> between 2 cons cells. This means GC needs both of these intact to be able to make
177 >> proper decision.
178 >> Will try to resolve this by adding some special symbols. But these must be symbols
179 >> that cannot occur normally in programs. Then an array could be:
180 
181  [Full pointer | ARRAY_SYM + GC_MARK]
182  |
183  [VECTOR]
184 
185 >> Boxed values same treatment as above.
186 >> TODO: Could this be simpler?
187 
188 [ VALUE | TYPE_SYM + GC_MARK]
189 
190 
191 0000 00XX XXXX XXXX XXXX XXXX XXXX X000 : 0x03FF FFF8
192 1111 AA00 0000 0000 0000 0000 0000 0000 : 0xFC00 0000 (AA bits left unused for now, future heap growth?)
193  */
194 #ifndef LBM64
195 
196 #define LBM_ADDRESS_SHIFT 2
197 #define LBM_VAL_SHIFT 4
198 
199 #define LBM_PTR_MASK 0x00000001u
200 #define LBM_PTR_BIT 0x00000001u
201 #define LBM_PTR_VAL_MASK 0x03FFFFFCu
202 #define LBM_PTR_TYPE_MASK 0xFC000000u
203 #define LBM_PTR_NULL (0x03FFFFFCu >> 2)
204 
205 // The address is an index into the const heap.
206 #define LBM_PTR_TO_CONSTANT_BIT 0x04000000u
207 #define LBM_PTR_TO_CONSTANT_MASK ~LBM_PTR_TO_CONSTANT_BIT
208 #define LBM_PTR_TO_CONSTANT_SHIFT 26
209 
210 #else /* 64 bit Version */
211 
212 #define LBM_ADDRESS_SHIFT 2
213 #define LBM_VAL_SHIFT 8
214 
215 #define LBM_PTR_MASK (lbm_uint)0x1
216 #define LBM_PTR_BIT (lbm_uint)0x1
217 #define LBM_PTR_VAL_MASK (lbm_uint)0x03FFFFFFFFFFFFFC
218 #define LBM_PTR_TYPE_MASK (lbm_uint)0xF800000000000000
219 #define LBM_PTR_NULL ((lbm_uint)0x03FFFFFFFFFFFFFC >> 2)
220 
221 #define LBM_PTR_TO_CONSTANT_BIT (lbm_uint)0x0400000000000000
222 #define LBM_PTR_TO_CONSTANT_MASK ~LBM_PTR_TO_CONSTANT_BIT
223 #define LBM_PTR_TO_CONSTANT_SHIFT 58
224 
225 #endif
226 
227 typedef enum {
228  LBM_FLASH_WRITE_OK,
229  LBM_FLASH_FULL,
230  LBM_FLASH_WRITE_ERROR
231 } lbm_flash_status;
232 
236 typedef struct {
237  lbm_value car;
238  lbm_value cdr;
239 } lbm_cons_t;
240 
244 typedef struct {
245  lbm_cons_t *heap;
246  lbm_value freelist; // list of free cons cells.
247  lbm_stack_t gc_stack;
248 
249  lbm_uint heap_size; // In number of cells.
250  lbm_uint heap_bytes; // In bytes.
251 
252  lbm_uint num_alloc; // Number of cells allocated.
253  lbm_uint num_alloc_arrays; // Number of arrays allocated.
254 
255  lbm_uint gc_num; // Number of times gc has been performed.
256  lbm_uint gc_marked; // Number of cells marked by mark phase.
257  lbm_uint gc_recovered; // Number of cells recovered by sweep phase.
258  lbm_uint gc_recovered_arrays;// Number of arrays recovered by sweep.
259  lbm_uint gc_least_free; // The smallest length of the freelist.
260  lbm_uint gc_last_free; // Number of elements on the freelist
261  // after most recent GC.
263 
264 extern lbm_heap_state_t lbm_heap_state;
265 
266 typedef bool (*const_heap_write_fun)(lbm_uint ix, lbm_uint w);
267 
268 typedef struct {
269  lbm_uint *heap;
270  lbm_uint next; // next free index.
271  lbm_uint size; // in lbm_uint words. (cons-cells = words / 2)
273 
279 typedef struct {
280  lbm_uint size;
281  lbm_uint *data;
283 
288 void lbm_gc_lock(void);
289 /* Unlock GC mutex
290  */
291 void lbm_gc_unlock(void);
292 
299 int lbm_heap_init(lbm_cons_t *addr, lbm_uint num_cells,
300  lbm_uint gc_stack_size);
301 
306 void lbm_heap_new_gc_time(lbm_uint dur);
316 lbm_uint lbm_heap_num_free(void);
321 lbm_uint lbm_heap_num_allocated(void);
326 lbm_uint lbm_heap_size(void);
331 lbm_uint lbm_heap_size_bytes(void);
351 lbm_value lbm_heap_allocate_list_init_va(unsigned int n, va_list valist);
375 lbm_uint lbm_dec_custom(lbm_value val);
387 uint32_t lbm_dec_as_u32(lbm_value val);
405 uint64_t lbm_dec_as_u64(lbm_value val);
418 
419 lbm_uint lbm_dec_raw(lbm_value v);
427 
486 // List functions
495 
504 unsigned int lbm_list_length_pred(lbm_value c, bool *pres, bool (*pred)(lbm_value));
530 
538 
544 lbm_value lbm_list_drop(unsigned int n, lbm_value ls);
545 
546 // State and statistics
556 lbm_uint lbm_get_gc_stack_max(void);
560 lbm_uint lbm_get_gc_stack_size(void);
561 // Garbage collection
565 void lbm_gc_state_inc(void);
569 void lbm_nil_freelist(void);
590 void lbm_gc_mark_aux(lbm_uint *data, lbm_uint n);
595 void lbm_gc_mark_roots(lbm_uint *roots, lbm_uint num_roots);
601 
602 // Array functionality
610 int lbm_heap_allocate_array(lbm_value *res, lbm_uint size);
619 int lbm_lift_array(lbm_value *value, char *data, lbm_uint num_elt);
639 lbm_uint lbm_size_of(lbm_type t);
640 
641 int lbm_const_heap_init(const_heap_write_fun w_fun,
642  lbm_const_heap_t *heap,
643  lbm_uint *addr,
644  lbm_uint num_words);
645 
646 lbm_flash_status lbm_allocate_const_cell(lbm_value *res);
647 lbm_flash_status lbm_write_const_raw(lbm_uint *data, lbm_uint n, lbm_uint *res);
648 lbm_flash_status write_const_cdr(lbm_value cell, lbm_value val);
649 lbm_flash_status write_const_car(lbm_value cell, lbm_value val);
650 lbm_uint lbm_flash_memory_usage(void);
651 
657 static inline lbm_type lbm_type_of(lbm_value x) {
658  return (x & LBM_PTR_MASK) ? (x & LBM_PTR_TYPE_MASK) : (x & LBM_VAL_TYPE_MASK);
659 }
660 
661 // type-of check that is safe in functional code
662 static inline lbm_type lbm_type_of_functional(lbm_value x) {
663  return (x & LBM_PTR_MASK) ?
664  (x & (LBM_PTR_TO_CONSTANT_MASK & LBM_PTR_TYPE_MASK)) :
665  (x & LBM_VAL_TYPE_MASK);
666 }
667 
668 static inline lbm_value lbm_enc_cons_ptr(lbm_uint x) {
669  return ((x << LBM_ADDRESS_SHIFT) | LBM_TYPE_CONS | LBM_PTR_BIT);
670 }
671 
672 static inline lbm_uint lbm_dec_ptr(lbm_value p) {
673  return ((LBM_PTR_VAL_MASK & p) >> LBM_ADDRESS_SHIFT);
674 }
675 
676 extern lbm_cons_t *lbm_heaps[2];
677 
678 static inline lbm_uint lbm_dec_cons_cell_ptr(lbm_value p) {
679  lbm_uint h = (p & LBM_PTR_TO_CONSTANT_BIT) >> LBM_PTR_TO_CONSTANT_SHIFT;
680  return lbm_dec_ptr(p) >> h;
681 }
682 
683 static inline lbm_cons_t *lbm_dec_heap(lbm_value p) {
684  lbm_uint h = (p & LBM_PTR_TO_CONSTANT_BIT) >> LBM_PTR_TO_CONSTANT_SHIFT;
685  return lbm_heaps[h];
686 }
687 
688 static inline lbm_value lbm_set_ptr_type(lbm_value p, lbm_type t) {
689  return ((LBM_PTR_VAL_MASK & p) | t | LBM_PTR_BIT);
690 }
691 
692 static inline lbm_value lbm_enc_sym(lbm_uint s) {
693  return (s << LBM_VAL_SHIFT) | LBM_TYPE_SYMBOL;
694 }
695 
696 static inline lbm_value lbm_enc_i(lbm_int x) {
697  return ((lbm_uint)x << LBM_VAL_SHIFT) | LBM_TYPE_I;
698 }
699 
700 static inline lbm_value lbm_enc_u(lbm_uint x) {
701  return (x << LBM_VAL_SHIFT) | LBM_TYPE_U;
702 }
703 
708 extern lbm_value lbm_enc_i32(int32_t x);
709 
714 extern lbm_value lbm_enc_u32(uint32_t x);
715 
720 extern lbm_value lbm_enc_float(float x);
721 
726 extern lbm_value lbm_enc_i64(int64_t x);
727 
732 extern lbm_value lbm_enc_u64(uint64_t x);
733 
738 extern lbm_value lbm_enc_double(double x);
739 
740 static inline lbm_value lbm_enc_char(char x) {
741  return ((lbm_uint)x << LBM_VAL_SHIFT) | LBM_TYPE_CHAR;
742 }
743 
744 static inline lbm_int lbm_dec_i(lbm_value x) {
745  return (lbm_int)x >> LBM_VAL_SHIFT;
746 }
747 
748 static inline lbm_uint lbm_dec_u(lbm_value x) {
749  return x >> LBM_VAL_SHIFT;
750 }
751 
752 static inline char lbm_dec_char(lbm_value x) {
753  return (char)(x >> LBM_VAL_SHIFT);
754 }
755 
756 static inline lbm_uint lbm_dec_sym(lbm_value x) {
757  return x >> LBM_VAL_SHIFT;
758 }
759 
764 extern float lbm_dec_float(lbm_value x);
765 
770 extern double lbm_dec_double(lbm_value x);
771 
772 
773 static inline uint32_t lbm_dec_u32(lbm_value x) {
774 #ifndef LBM64
775  return (uint32_t)lbm_car(x);
776 #else
777  return (uint32_t)(x >> LBM_VAL_SHIFT);
778 #endif
779 }
780 
785 extern uint64_t lbm_dec_u64(lbm_value x);
786 
787 static inline int32_t lbm_dec_i32(lbm_value x) {
788 #ifndef LBM64
789  return (int32_t)lbm_car(x);
790 #else
791  return (int32_t)(x >> LBM_VAL_SHIFT);
792 #endif
793 }
794 
799 extern int64_t lbm_dec_i64(lbm_value x);
800 
801 static inline bool lbm_is_ptr(lbm_value x) {
802  return (x & LBM_PTR_MASK);
803 }
804 
805 static inline bool lbm_is_cons_rw(lbm_value x) {
806  return (lbm_type_of(x) == LBM_TYPE_CONS);
807 }
808 
809 static inline bool lbm_is_cons(lbm_value x) {
810  lbm_type t = lbm_type_of(x);
811  return (t == LBM_TYPE_CONS ||
812  t == (LBM_TYPE_CONS | LBM_PTR_TO_CONSTANT_BIT));
813 }
814 
819 extern bool lbm_is_number(lbm_value x);
820 
825 static inline bool lbm_is_array_r(lbm_value x) {
826  lbm_type t = lbm_type_of(x);
827  return ((t & LBM_PTR_TO_CONSTANT_MASK) == LBM_TYPE_ARRAY);
828 }
829 
830 static inline bool lbm_is_array_rw(lbm_value x) {
831  return( (lbm_type_of(x) == LBM_TYPE_ARRAY) && !(x & LBM_PTR_TO_CONSTANT_BIT));
832 }
833 
834 static inline bool lbm_is_channel(lbm_value x) {
835  return (lbm_type_of(x) == LBM_TYPE_CHANNEL &&
836  lbm_type_of(lbm_cdr(x)) == LBM_TYPE_SYMBOL &&
837  lbm_dec_sym(lbm_cdr(x)) == SYM_CHANNEL_TYPE);
838 }
839 static inline bool lbm_is_char(lbm_value x) {
840  return (lbm_type_of(x) == LBM_TYPE_CHAR);
841 }
842 
843 static inline bool lbm_is_special(lbm_value symrep) {
844  return ((lbm_type_of(symrep) == LBM_TYPE_SYMBOL) &&
845  (lbm_dec_sym(symrep) < SPECIAL_SYMBOLS_END));
846 }
847 
848 static inline bool lbm_is_closure(lbm_value exp) {
849  return ((lbm_is_cons(exp)) &&
850  (lbm_type_of(lbm_car(exp)) == LBM_TYPE_SYMBOL) &&
851  (lbm_dec_sym(lbm_car(exp)) == SYM_CLOSURE));
852 }
853 
854 static inline bool lbm_is_continuation(lbm_value exp) {
855  return ((lbm_type_of(exp) == LBM_TYPE_CONS) &&
856  (lbm_type_of(lbm_car(exp)) == LBM_TYPE_SYMBOL) &&
857  (lbm_dec_sym(lbm_car(exp)) == SYM_CONT));
858 }
859 
860 static inline bool lbm_is_macro(lbm_value exp) {
861  return ((lbm_type_of(exp) == LBM_TYPE_CONS) &&
862  (lbm_type_of(lbm_car(exp)) == LBM_TYPE_SYMBOL) &&
863  (lbm_dec_sym(lbm_car(exp)) == SYM_MACRO));
864 }
865 
866 static inline bool lbm_is_match_binder(lbm_value exp) {
867  return (lbm_is_cons(exp) &&
868  (lbm_type_of(lbm_car(exp)) == LBM_TYPE_SYMBOL) &&
869  ((lbm_dec_sym(lbm_car(exp)) == SYM_MATCH_ANY)));
870 }
871 
872 static inline bool lbm_is_comma_qualified_symbol(lbm_value exp) {
873  return (lbm_is_cons(exp) &&
874  (lbm_type_of(lbm_car(exp)) == LBM_TYPE_SYMBOL) &&
875  (lbm_dec_sym(lbm_car(exp)) == SYM_COMMA) &&
876  (lbm_type_of(lbm_car(lbm_cdr(exp))) == LBM_TYPE_SYMBOL));
877 }
878 
879 static inline bool lbm_is_symbol(lbm_value exp) {
880  return (lbm_type_of(exp) == LBM_TYPE_SYMBOL);
881 }
882 
883 static inline bool lbm_is_symbol_nil(lbm_value exp) {
884  return (lbm_is_symbol(exp) && lbm_dec_sym(exp) == SYM_NIL);
885 }
886 
887 static inline bool lbm_is_symbol_true(lbm_value exp) {
888  return (lbm_is_symbol(exp) && lbm_dec_sym(exp) == SYM_TRUE);
889 }
890 
891 static inline bool lbm_is_symbol_eval(lbm_value exp) {
892  return (lbm_is_symbol(exp) && lbm_dec_sym(exp) == SYM_EVAL);
893 }
894 
895 static inline bool lbm_is_symbol_merror(lbm_value exp) {
896  return (lbm_is_symbol(exp) && lbm_dec_sym(exp) == SYM_MERROR);
897 }
898 
899 static inline bool lbm_is_list(lbm_value x) {
900  return (lbm_is_cons(x) || lbm_is_symbol_nil(x));
901 }
902 
903 static inline bool lbm_is_list_rw(lbm_value x) {
904  return (lbm_is_cons_rw(x) || lbm_is_symbol_nil(x));
905 }
906 
907 static inline bool lbm_is_quoted_list(lbm_value x) {
908  return (lbm_is_cons(x) &&
909  lbm_is_symbol(lbm_car(x)) &&
910  (lbm_dec_sym(lbm_car(x)) == SYM_QUOTE) &&
911  lbm_is_cons(lbm_cdr(x)) &&
912  lbm_is_cons(lbm_car(lbm_cdr(x))));
913 }
914 
915 #ifndef LBM64
916 #define ERROR_SYMBOL_MASK 0xFFFFFFF0
917 #else
918 #define ERROR_SYMBOL_MASK 0xFFFFFFFFFFFFFFF0
919 #endif
920 
921 /* all error signaling symbols are in the range 0x20 - 0x2F */
922 static inline bool lbm_is_error(lbm_value v){
923  return (lbm_type_of(v) == LBM_TYPE_SYMBOL &&
924  ((lbm_dec_sym(v) & ERROR_SYMBOL_MASK) == 0x20));
925 }
926 
927 // ref_cell: returns a reference to the cell addressed by bits 3 - 26
928 // Assumes user has checked that is_ptr was set
929 static inline lbm_cons_t* lbm_ref_cell(lbm_value addr) {
930  return &lbm_dec_heap(addr)[lbm_dec_cons_cell_ptr(addr)];
931  //return &lbm_heap_state.heap[lbm_dec_ptr(addr)];
932 }
933 
934 
935 // lbm_uint a = lbm_heaps[0];
936 // lbm_uint b = lbm_heaps[1];
937 // lbm_uint i = (addr & LBM_PTR_TO_CONSTANT_BIT) >> LBM_PTR_TO_CONSTANT_SHIFT) - 1;
938 // lbm_uint h = (a & i) | (b & ~i);
939 
940 #ifdef __cplusplus
941 }
942 #endif
943 #endif
int32_t lbm_dec_as_i32(lbm_value val)
lbm_uint lbm_heap_size_bytes(void)
lbm_value lbm_enc_double(double x)
lbm_value lbm_list_reverse(lbm_value list)
int64_t lbm_dec_as_i64(lbm_value val)
void lbm_gc_mark_env(lbm_value)
lbm_value lbm_list_append(lbm_value list1, lbm_value list2)
uint8_t * lbm_heap_array_get_data(lbm_value arr)
void lbm_heap_new_gc_time(lbm_uint dur)
lbm_value lbm_cddr(lbm_value c)
lbm_uint lbm_dec_custom(lbm_value val)
lbm_uint lbm_heap_num_free(void)
lbm_value lbm_heap_allocate_cell(lbm_type type, lbm_value car, lbm_value cdr)
lbm_uint lbm_get_gc_stack_max(void)
lbm_value lbm_enc_float(float x)
lbm_char_channel_t * lbm_dec_channel(lbm_value val)
double lbm_dec_as_double(lbm_value val)
static bool lbm_is_array_r(lbm_value x)
Definition: heap.h:825
void lbm_get_heap_state(lbm_heap_state_t *)
lbm_value lbm_cons(lbm_value car, lbm_value cdr)
void lbm_gc_lock(void)
lbm_int lbm_heap_array_get_size(lbm_value arr)
lbm_value lbm_list_copy(int *m, lbm_value list)
int lbm_lift_array(lbm_value *value, char *data, lbm_uint num_elt)
int lbm_set_car(lbm_value c, lbm_value v)
lbm_value lbm_cdr(lbm_value cons)
void lbm_gc_mark_aux(lbm_uint *data, lbm_uint n)
void lbm_gc_state_inc(void)
lbm_value lbm_heap_allocate_list(lbm_uint n)
lbm_value lbm_caar(lbm_value c)
bool lbm_is_number(lbm_value x)
int lbm_heap_allocate_array(lbm_value *res, lbm_uint size)
lbm_uint lbm_list_length(lbm_value c)
lbm_uint lbm_size_of(lbm_type t)
uint64_t lbm_dec_u64(lbm_value x)
lbm_value lbm_heap_allocate_list_init(unsigned int n,...)
lbm_uint lbm_heap_size(void)
static lbm_type lbm_type_of(lbm_value x)
Definition: heap.h:657
int lbm_set_cdr(lbm_value c, lbm_value v)
char * lbm_dec_str(lbm_value val)
int lbm_heap_init(lbm_cons_t *addr, lbm_uint num_cells, lbm_uint gc_stack_size)
uint64_t lbm_dec_as_u64(lbm_value val)
lbm_value lbm_car(lbm_value cons)
lbm_value lbm_cadr(lbm_value c)
lbm_value lbm_enc_u32(uint32_t x)
char lbm_dec_as_char(lbm_value a)
int lbm_set_car_and_cdr(lbm_value c, lbm_value car_val, lbm_value cdr_val)
lbm_value lbm_enc_i32(int32_t x)
void lbm_heap_new_freelist_length(void)
lbm_value lbm_enc_i64(int64_t x)
lbm_value lbm_enc_u64(uint64_t x)
int lbm_gc_sweep_phase(void)
float lbm_dec_as_float(lbm_value val)
unsigned int lbm_list_length_pred(lbm_value c, bool *pres, bool(*pred)(lbm_value))
void lbm_nil_freelist(void)
int lbm_heap_explicit_free_array(lbm_value arr)
lbm_uint lbm_get_gc_stack_size(void)
lbm_value lbm_list_drop(unsigned int n, lbm_value ls)
lbm_uint lbm_heap_num_allocated(void)
void lbm_gc_mark_roots(lbm_uint *roots, lbm_uint num_roots)
lbm_value lbm_heap_allocate_list_init_va(unsigned int n, va_list valist)
int lbm_gc_mark_freelist(void)
float lbm_dec_float(lbm_value x)
uint32_t lbm_dec_as_u32(lbm_value val)
lbm_value lbm_list_destructive_reverse(lbm_value list)
int64_t lbm_dec_i64(lbm_value x)
void lbm_gc_mark_phase(lbm_value root)
double lbm_dec_double(lbm_value x)
uint32_t lbm_type
Definition: lbm_types.h:45
uint32_t lbm_value
Definition: lbm_types.h:43
Definition: heap.h:279
lbm_uint * data
Number of elements.
Definition: heap.h:281
Definition: lbm_channel.h:68
Definition: heap.h:236
Definition: heap.h:268
Definition: heap.h:244
Definition: stack.h:33