.
This commit is contained in:
2
Makefile
2
Makefile
@@ -30,7 +30,7 @@ endif
|
||||
|
||||
# debug and release flags
|
||||
|
||||
DEBUG_CFLAGS=-Og -ggdb3 ${WARNINGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined \
|
||||
DEBUG_CFLAGS=-O0 -ggdb3 ${WARNINGS} -fno-omit-frame-pointer -fsanitize=address -fsanitize=undefined \
|
||||
-fno-sanitize-recover=all -fstack-protector-strong -fstack-clash-protection -fno-common ${ADD_DBG_FLAGS} \
|
||||
-DCHECK_TYCHE_BUGS=1
|
||||
DEBUG_LDFLAGS=-fsanitize=address -fsanitize=undefined
|
||||
|
||||
35
lib/heap.c
35
lib/heap.c
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "khash.h"
|
||||
|
||||
@@ -18,7 +19,7 @@ typedef struct {
|
||||
// TODO - array and table
|
||||
} value;
|
||||
} HeapValue;
|
||||
KHASH_MAP_INIT_INT(HEAP, HeapValue)
|
||||
KHASH_MAP_INIT_INT64(HEAP, HeapValue)
|
||||
|
||||
typedef struct {
|
||||
khash_t(HEAP) *items;
|
||||
@@ -29,10 +30,8 @@ static void heap_init(Heap* h)
|
||||
h->items = kh_init(HEAP);
|
||||
}
|
||||
|
||||
static void heap_finalize(Heap* h)
|
||||
static void heap_free_item(HeapValue value)
|
||||
{
|
||||
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
||||
HeapValue value = kh_value(h->items, k);
|
||||
switch (value.type) {
|
||||
case TH_STRING:
|
||||
free(value.value.str);
|
||||
@@ -44,6 +43,15 @@ static void heap_finalize(Heap* h)
|
||||
abort(); // not implemented yet
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void heap_finalize(Heap* h)
|
||||
{
|
||||
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
||||
if (kh_exist(h->items, k)) {
|
||||
HeapValue value = kh_value(h->items, k);
|
||||
heap_free_item(value);
|
||||
}
|
||||
}
|
||||
kh_destroy(HEAP, h->items);
|
||||
}
|
||||
@@ -88,7 +96,8 @@ static size_t heap_size(Heap* h)
|
||||
// GC
|
||||
//
|
||||
|
||||
KHASH_MAP_INIT_INT(MARK, bool)
|
||||
KHASH_MAP_INIT_INT64(MARK, bool)
|
||||
|
||||
static void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
||||
{
|
||||
//
|
||||
@@ -100,7 +109,8 @@ static void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
||||
for (size_t i = 0; i < n_roots; ++i) {
|
||||
if (value_type(roots[i]) == TT_STRING) {
|
||||
int ret;
|
||||
khiter_t k = kh_put(MARK, marked, value_idx(roots[i]), &ret);
|
||||
uint32_t key = value_idx(roots[i]);
|
||||
khiter_t k = kh_put(MARK, marked, key, &ret);
|
||||
kh_value(marked, k) = true;
|
||||
}
|
||||
}
|
||||
@@ -109,10 +119,15 @@ static void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
||||
// sweep
|
||||
//
|
||||
|
||||
for (khiter_t k = kh_begin(marked); k != kh_end(marked); ++k) {
|
||||
HEAP_KEY key = kh_value(marked, k);
|
||||
khiter_t item = kh_get(HEAP, h->items, key);
|
||||
kh_del(HEAP, h->items, item);
|
||||
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
||||
if (kh_exist(h->items, k)) {
|
||||
HEAP_KEY key = kh_key(h->items, k);
|
||||
if (kh_get(MARK, marked, key) == kh_end(marked)) {
|
||||
khiter_t kk = kh_get(HEAP, h->items, key);
|
||||
heap_free_item(kh_value(h->items, kk));
|
||||
kh_del(HEAP, h->items, kk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kh_destroy(MARK, marked);
|
||||
|
||||
33
test/tests.c
33
test/tests.c
@@ -93,7 +93,7 @@ int main()
|
||||
}
|
||||
|
||||
{
|
||||
printf("### Heap\n");
|
||||
printf("### Heap - strings\n");
|
||||
|
||||
Heap h;
|
||||
heap_init(&h);
|
||||
@@ -108,4 +108,35 @@ int main()
|
||||
|
||||
heap_finalize(&h);
|
||||
}
|
||||
|
||||
{
|
||||
printf("### Heap - string GC\n");
|
||||
|
||||
Stack s;
|
||||
stack_init(&s);
|
||||
|
||||
Heap h;
|
||||
heap_init(&h);
|
||||
|
||||
stack_push(&s, create_value_idx(TT_STRING, heap_add_string(&h, "item1")));
|
||||
stack_push(&s, create_value_idx(TT_STRING, heap_add_string(&h, "item2")));
|
||||
stack_push(&s, create_value_idx(TT_STRING, heap_add_string(&h, "item3")));
|
||||
|
||||
assert(heap_size(&h) == 3);
|
||||
heap_gc(&h, s.stack, s.stack_n);
|
||||
assert(heap_size(&h) == 3);
|
||||
|
||||
stack_pop(&s, NULL);
|
||||
|
||||
assert(heap_size(&h) == 3);
|
||||
heap_gc(&h, s.stack, s.stack_n);
|
||||
assert(heap_size(&h) == 2);
|
||||
|
||||
stack_pop(&s, NULL);
|
||||
heap_gc(&h, s.stack, s.stack_n);
|
||||
assert(heap_size(&h) == 1);
|
||||
|
||||
heap_finalize(&h);
|
||||
stack_finalize(&s);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user