.
This commit is contained in:
2
Makefile
2
Makefile
@@ -30,7 +30,7 @@ endif
|
|||||||
|
|
||||||
# debug and release flags
|
# 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} \
|
-fno-sanitize-recover=all -fstack-protector-strong -fstack-clash-protection -fno-common ${ADD_DBG_FLAGS} \
|
||||||
-DCHECK_TYCHE_BUGS=1
|
-DCHECK_TYCHE_BUGS=1
|
||||||
DEBUG_LDFLAGS=-fsanitize=address -fsanitize=undefined
|
DEBUG_LDFLAGS=-fsanitize=address -fsanitize=undefined
|
||||||
|
|||||||
35
lib/heap.c
35
lib/heap.c
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "khash.h"
|
#include "khash.h"
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ typedef struct {
|
|||||||
// TODO - array and table
|
// TODO - array and table
|
||||||
} value;
|
} value;
|
||||||
} HeapValue;
|
} HeapValue;
|
||||||
KHASH_MAP_INIT_INT(HEAP, HeapValue)
|
KHASH_MAP_INIT_INT64(HEAP, HeapValue)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
khash_t(HEAP) *items;
|
khash_t(HEAP) *items;
|
||||||
@@ -29,10 +30,8 @@ static void heap_init(Heap* h)
|
|||||||
h->items = kh_init(HEAP);
|
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) {
|
switch (value.type) {
|
||||||
case TH_STRING:
|
case TH_STRING:
|
||||||
free(value.value.str);
|
free(value.value.str);
|
||||||
@@ -44,6 +43,15 @@ static void heap_finalize(Heap* h)
|
|||||||
abort(); // not implemented yet
|
abort(); // not implemented yet
|
||||||
break;
|
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);
|
kh_destroy(HEAP, h->items);
|
||||||
}
|
}
|
||||||
@@ -88,7 +96,8 @@ static size_t heap_size(Heap* h)
|
|||||||
// GC
|
// 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)
|
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) {
|
for (size_t i = 0; i < n_roots; ++i) {
|
||||||
if (value_type(roots[i]) == TT_STRING) {
|
if (value_type(roots[i]) == TT_STRING) {
|
||||||
int ret;
|
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;
|
kh_value(marked, k) = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,10 +119,15 @@ static void heap_gc(Heap* h, VALUE const* roots, size_t n_roots)
|
|||||||
// sweep
|
// sweep
|
||||||
//
|
//
|
||||||
|
|
||||||
for (khiter_t k = kh_begin(marked); k != kh_end(marked); ++k) {
|
for (khiter_t k = kh_begin(h->items); k != kh_end(h->items); ++k) {
|
||||||
HEAP_KEY key = kh_value(marked, k);
|
if (kh_exist(h->items, k)) {
|
||||||
khiter_t item = kh_get(HEAP, h->items, key);
|
HEAP_KEY key = kh_key(h->items, k);
|
||||||
kh_del(HEAP, h->items, item);
|
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);
|
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 h;
|
||||||
heap_init(&h);
|
heap_init(&h);
|
||||||
@@ -108,4 +108,35 @@ int main()
|
|||||||
|
|
||||||
heap_finalize(&h);
|
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