- signal 4 on datastack underflow on mac intel??
- test alien-indirect
+- code GC:
+ - get code heap load/save working
+ - get room. working
+ - compact the heap on save
+ ui:
- figure out if we need both set-model and set-model*
- if i do 10000 [ . ] each and then clear, the listener window is slow
- full-height nodes should really be full height
-- draw-world: bail out if world is 0x0
- better help result ranking
- page scrolling should be timer-based too
- x11: scroll up/down wiggles caret
- float= doesn't consider nans equal
- intrinsic fixnum>float float>fixnum
- C functions returning structs by value
-- code gc
- infer which variables are read, written in a quotation
- compiled continuations
- compiled call traces
heap->free_list = NULL;
}
-INLINE CELL block_size(F_BLOCK *block)
-{
- return (CELL)block->next - (CELL)block - sizeof(F_BLOCK);
-}
-
INLINE void update_free_list(HEAP *heap, F_BLOCK *prev, F_BLOCK *next_free)
{
if(prev)
F_BLOCK *scan = (F_BLOCK *)heap->base;
F_BLOCK *end = (F_BLOCK *)(heap->base + size);
- while(scan < end)
+ while(scan && scan < end)
{
if(scan->status == B_FREE)
{
prev = scan;
}
- scan = scan->next;
+ scan = next_block(heap,scan);
}
if((CELL)(end + 1) <= heap->limit)
{
end->status = B_FREE;
end->next_free = NULL;
- end->next = NULL;
- update_free_list(heap,prev,end);
+ end->size = heap->limit - (CELL)end;
}
else
- update_free_list(heap,prev,NULL);
+ {
+ end = NULL;
+
+ if(prev)
+ prev->size = heap->limit - (CELL)prev;
+ }
+
+ update_free_list(heap,prev,end);
}
CELL heap_allot(HEAP *heap, CELL size)
while(scan)
{
- if(block_size(scan) >= size)
- {
- /* we found a candidate block */
- F_BLOCK *next_free;
+ CELL this_size = scan->size - sizeof(F_BLOCK);
- if(block_size(scan) <= size + sizeof(F_BLOCK))
- {
- /* too small to be split */
- next_free = scan->next_free;
- }
- else
- {
- /* split the block in two */
- F_BLOCK *split = (F_BLOCK *)((CELL)scan + size);
- split->status = B_FREE;
- split->next_free = scan->next_free;
- next_free = split;
- }
+ if(this_size < size)
+ {
+ prev = scan;
+ scan = scan->next_free;
+ continue;
+ }
- /* update the free list */
- update_free_list(heap,prev,next_free);
+ /* we found a candidate block */
+ F_BLOCK *next_free;
- /* this is our new block */
- scan->status = B_ALLOCATED;
- return (CELL)(scan + 1);
+ if(this_size - size <= sizeof(F_BLOCK))
+ {
+ /* too small to be split */
+ next_free = scan->next_free;
}
+ else
+ {
+ /* split the block in two */
+ CELL new_size = size + sizeof(F_BLOCK);
+ F_BLOCK *split = (F_BLOCK *)((CELL)scan + new_size);
+ split->status = B_FREE;
+ split->size = scan->size - new_size;
+ split->next_free = scan->next_free;
+ scan->size = new_size;
+ next_free = split;
+ }
+
+ /* update the free list */
+ update_free_list(heap,prev,next_free);
+
+ /* this is our new block */
+ scan->status = B_ALLOCATED;
- prev = scan;
- scan = scan->next_free;
+ return (CELL)(scan + 1);
}
if(heap->base == 0)
if(scan->status == B_ALLOCATED)
{
/* merge blocks? */
- if(prev->next == scan)
- prev->next = scan->next;
+ if(next_block(heap,prev) == scan)
+ prev->size += scan->size;
else
{
scan->status = B_FREE;
}
}
- scan = scan->next;
+ scan = next_block(heap,scan);
}
if(prev)
prev->next_free = NULL;
}
-
-void iterate_heap(HEAP *heap, HEAP_ITERATOR iter)
-{
- F_BLOCK *scan = (F_BLOCK *)heap->base;
- while(scan)
- {
- iter((CELL)(scan + 1),scan->status);
- scan = scan->next;
- }
-}
typedef struct _F_BLOCK
{
F_BLOCK_STATUS status;
+ CELL size;
struct _F_BLOCK *next_free;
- struct _F_BLOCK *next;
} F_BLOCK;
typedef struct {
F_BLOCK *free_list;
} HEAP;
-typedef void (*HEAP_ITERATOR)(CELL here, F_BLOCK_STATUS status);
-
void new_heap(HEAP *heap, CELL size);
void build_free_list(HEAP *heap, CELL size);
CELL heap_allot(HEAP *heap, CELL size);
void free_unmarked(HEAP *heap);
+
+INLINE F_BLOCK *next_block(HEAP *heap, F_BLOCK *block)
+{
+ CELL next = ((CELL)block + block->size);
+ if(next == heap->limit)
+ return NULL;
+ else
+ return (F_BLOCK *)next;
+}