1 /******************************************************
8 * Copyright (c) 2006, 2007 Charles R. Childers
10 * Permission to use, copy, modify, and distribute this
11 * software for any purpose with or without fee is hereby
12 * granted, provided that the above copyright notice and
13 * this permission notice appear in all copies.
15 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR
16 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
19 * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
20 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
21 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
22 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 ******************************************************/
33 extern VM_STACK data
, address
, alternate
;
37 /******************************************************
39 *|F| GCITEM gc_list[128]
40 *|F| Holds the list of items marked as garbage
43 *|F| A pointer to the top of the garbage collection
46 *|F| GCITEM gc_trash[128]
47 *|F| Holds the short list of items marked as garbage
50 *|F| A pointer to the top of the short garbage
54 *|F| Contains the total size of all currently used
55 *|F| memory, including permanent quotes.
58 *|F| Contains the total number of objects that are
59 *|F| currently existing, including permanent ones.
61 ******************************************************/
62 long gc_used
= 0, gc_objects
= 0;
63 GCITEM gc_list
[128]; long gc_depth
= 0;
64 GCITEM gc_trash
[128]; long gc_tdepth
= 0;
68 /******************************************************
69 *|F| gc_alloc(long items, long size, long type)
70 *|F| Allocate the requested memory and add it to the
71 *|F| garbage collection list.
72 *|F| If type is set to GC_MEM, add to the normal garbage
73 *|F| collection list. If set to GC_TRASH, add to the short
74 *|F| list of known garbage items which can be safely
75 *|F| freed at the next gc().
76 *|F| If the allocation fails, gc() is called, and the
77 *|F| allocation is retried. If it still fails, an
78 *|F| error is reported and Toka is terminated.
80 ******************************************************/
81 void *gc_alloc(long items
, long size
, long type
)
85 if (gc_depth
== 127 || gc_tdepth
== 127)
88 memory
= calloc((int)items
, (int)size
);
93 memory
= calloc((int)items
, (int)size
);
98 memset(memory
, 0, size
* items
);
102 gc_list
[gc_depth
].xt
= (Inst
)memory
;
103 gc_list
[gc_depth
].size
= size
* items
;
108 gc_trash
[gc_tdepth
].xt
= (Inst
)memory
;
109 gc_trash
[gc_tdepth
].size
= size
* items
;
113 gc_used
+= size
* items
;
121 /******************************************************
122 *|G| keep ( a-a ) Mark quotes/allocated memory
126 *|F| Remove the specified address (and any childern it
127 *|F| has registered) from the garbage collection list.
128 *|F| If the TOS is not an allocated address, this will
129 *|F| silently ignore it.
131 ******************************************************/
136 Inst item
= (Inst
)TOS
;
139 for (a
= 0; a
!= gc_depth
; a
++)
141 if (gc_list
[a
].xt
== item
)
147 for (a
= gc_depth
; a
> which
; a
--)
154 /******************************************************
155 *|G| gc ( - ) Clean the garbage
158 *|F| Free the oldest allocations on the garbage list.
159 *|F| Will free up to 64 trash entries and 32 normal
160 *|F| entries per call.
162 ******************************************************/
167 /* Allocations known to be temporary */
173 for (a
= 0; a
!= b
; a
++)
175 free(gc_trash
[a
].xt
);
176 gc_used
-= gc_trash
[a
].size
;
183 for (a
= 0; a
!= gc_tdepth
; a
++)
185 gc_trash
[a
].xt
= gc_trash
[a
+b
].xt
;
186 gc_trash
[a
].size
= gc_trash
[a
+b
].size
;
193 /* General Allocations */
199 for (a
= 0; a
!= b
; a
++)
202 gc_used
-= gc_list
[a
].size
;
209 for (a
= 0; a
!= gc_depth
; a
++)
211 gc_list
[a
].xt
= gc_list
[a
+b
].xt
;
212 gc_list
[a
].size
= gc_list
[a
+b
].size
;
221 /******************************************************
222 *|G| malloc ( n-a ) Allocate 'n' bytes of memory
225 *|F| Allocate TOS bytes of memory. Returns a pointer to
226 *|F| the allocated memory.
228 ******************************************************/
231 TOS
= (long)gc_alloc(TOS
, sizeof(char), GC_MEM
);