mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-16 19:58:46 +00:00
fix closure and sexp copiyng; fix sacn_custom_data; redo heap managing
This commit is contained in:
parent
faca5c6e0e
commit
b4f3c22704
2 changed files with 78 additions and 47 deletions
|
|
@ -13,7 +13,7 @@ $(TESTS): %: %.expr
|
||||||
$(RC) $< && cat $@.input | ./$@ > $@.log && diff $@.log orig/$@.log
|
$(RC) $< && cat $@.input | ./$@ > $@.log && diff $@.log orig/$@.log
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) test*.log *.s *~ $(TESTS)
|
$(RM) test*.log *.s *~ $(TESTS) *.i
|
||||||
$(MAKE) clean -C expressions
|
$(MAKE) clean -C expressions
|
||||||
$(MAKE) clean -C deep-expressions
|
$(MAKE) clean -C deep-expressions
|
||||||
$(MAKE) clean -C x86only
|
$(MAKE) clean -C x86only
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
# define alloc malloc
|
# define alloc malloc
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/*# define DEBUG_PRINT 1 */
|
/* # define DEBUG_PRINT 1 */
|
||||||
|
|
||||||
/* GC pool structure and data; declared here in order to allow debug print */
|
/* GC pool structure and data; declared here in order to allow debug print */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -90,7 +90,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int tag;
|
int tag;
|
||||||
data contents;
|
data contents;
|
||||||
} sexp;
|
} sexp;
|
||||||
|
|
||||||
extern void* alloc (size_t);
|
extern void* alloc (size_t);
|
||||||
extern void* Bsexp (int n, ...);
|
extern void* Bsexp (int n, ...);
|
||||||
|
|
@ -1037,26 +1037,50 @@ extern void __gc_root_scan_stack ();
|
||||||
/* Mark-and-copy */
|
/* Mark-and-copy */
|
||||||
/* ======================================== */
|
/* ======================================== */
|
||||||
|
|
||||||
//static size_t SPACE_SIZE = 128;
|
static size_t SPACE_SIZE = 32;
|
||||||
static size_t SPACE_SIZE = 1024 * 1024;
|
// static size_t SPACE_SIZE = 128;
|
||||||
# define POOL_SIZE (2*SPACE_SIZE)
|
// static size_t SPACE_SIZE = 1024 * 1024;
|
||||||
|
|
||||||
static void swap (size_t ** a, size_t ** b) {
|
static int free_pool (pool * p) {
|
||||||
size_t * t = *a;
|
size_t *a = p->begin, b = p->size;
|
||||||
*a = *b;
|
p->begin = NULL;
|
||||||
*b = t;
|
p->size = 0;
|
||||||
|
p->end = NULL;
|
||||||
|
p->current = NULL;
|
||||||
|
return munmap((void *)a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_to_space (void) {
|
||||||
|
size_t space_size = SPACE_SIZE * sizeof(size_t);
|
||||||
|
to_space.begin = mmap (NULL, space_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
|
||||||
|
if (to_space.begin == MAP_FAILED) {
|
||||||
|
perror ("EROOR: init_to_space: mmap failed\n");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
to_space.current = to_space.begin;
|
||||||
|
to_space.end = to_space.begin + SPACE_SIZE;
|
||||||
|
to_space.size = SPACE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gc_swap_spaces (void) {
|
static void gc_swap_spaces (void) {
|
||||||
swap (&from_space.begin, &to_space.begin);
|
#ifdef DEBUG_PRINT
|
||||||
swap (&from_space.end , &to_space.end );
|
printf ("gc_swap_spaces\n"); fflush (stdout);
|
||||||
|
#endif
|
||||||
|
free_pool (&from_space);
|
||||||
|
from_space.begin = to_space.begin;
|
||||||
from_space.current = current;
|
from_space.current = current;
|
||||||
to_space.current = to_space.begin;
|
from_space.end = to_space.end;
|
||||||
|
from_space.size = to_space.size;
|
||||||
|
to_space.begin = NULL;
|
||||||
|
to_space.current = NULL;
|
||||||
|
to_space.end = NULL;
|
||||||
|
to_space.size = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
# define IS_VALID_HEAP_POINTER(p)\
|
# define IS_VALID_HEAP_POINTER(p)\
|
||||||
(!UNBOXED(p) && \
|
(!UNBOXED(p) && \
|
||||||
from_space.begin <= p && \
|
from_space.begin <= p && \
|
||||||
from_space.end > p)
|
from_space.end > p)
|
||||||
|
|
||||||
# define IN_PASSIVE_SPACE(p) \
|
# define IN_PASSIVE_SPACE(p) \
|
||||||
|
|
@ -1071,42 +1095,53 @@ extern size_t * gc_copy (size_t *obj);
|
||||||
static void copy_elements (size_t *where, size_t *from, int len) {
|
static void copy_elements (size_t *where, size_t *from, int len) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
void * p = NULL;
|
void * p = NULL;
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf ("copy_elements: start; len = %d\n", len); fflush (stdout);
|
||||||
|
#endif
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
size_t elem = from[i];
|
size_t elem = from[i];
|
||||||
if (!IS_VALID_HEAP_POINTER(elem)) {
|
if (!IS_VALID_HEAP_POINTER(elem)) {
|
||||||
*where = elem;
|
*where = elem;
|
||||||
where++;
|
where++;
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf ("copy_elements: copy NON ptr: %zu\n", elem); fflush (stdout);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = gc_copy ((size_t*) elem);
|
p = gc_copy ((size_t*) elem);
|
||||||
*where = p;
|
*where = p;
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("copy_elements: fix %p: %p\n", from, *where); fflush (stdout);
|
printf ("copy_elements: fix element: %p -> %p\n", elem, *where); fflush (stdout);
|
||||||
#endif
|
#endif
|
||||||
where ++;
|
where ++;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf ("copy_elements: iteration end: where = %p, *where = %p, i = %d, len = %d\n", where, *where, i, len); fflush (stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG_PRINT
|
||||||
|
printf ("copy_elements: end\n"); fflush (stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extend_spaces (void) {
|
static void extend_spaces (void) {
|
||||||
void *p1 = (void *) BOX (NULL), *p2 = (void *) BOX (NULL);
|
void *p = (void *) BOX (NULL);
|
||||||
size_t old_space_size = SPACE_SIZE * sizeof(size_t),
|
size_t old_space_size = SPACE_SIZE * sizeof(size_t),
|
||||||
new_space_size = (SPACE_SIZE << 1) * sizeof(size_t);
|
new_space_size = (SPACE_SIZE << 1) * sizeof(size_t);
|
||||||
p1 = mremap(from_space.begin, old_space_size, new_space_size, 0);
|
p = mremap(to_space.begin, old_space_size, new_space_size, 0);
|
||||||
p2 = mremap(to_space.begin , old_space_size, new_space_size, 0);
|
if (p == MAP_FAILED) {
|
||||||
if (p1 == MAP_FAILED || p2 == MAP_FAILED) {
|
|
||||||
perror("EROOR: extend_spaces: mmap failed\n");
|
perror("EROOR: extend_spaces: mmap failed\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("extend: %p %p %p %p\n", p1, p2, from_space.begin, to_space.begin);
|
printf ("extend: %p %p\n", p, to_space.begin);
|
||||||
printf ("extend: %p %p %p\n" , from_space.end, to_space.end, current);
|
printf ("extend: %p %p\n", to_space.end, current);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
#endif
|
#endif
|
||||||
from_space.end += SPACE_SIZE;
|
|
||||||
to_space.end += SPACE_SIZE;
|
to_space.end += SPACE_SIZE;
|
||||||
SPACE_SIZE = SPACE_SIZE << 1;
|
SPACE_SIZE = SPACE_SIZE << 1;
|
||||||
from_space.size = SPACE_SIZE;
|
|
||||||
to_space.size = SPACE_SIZE;
|
to_space.size = SPACE_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1141,7 +1176,7 @@ extern size_t * gc_copy (size_t *obj) {
|
||||||
|
|
||||||
if (IS_FORWARD_PTR(d->tag)) {
|
if (IS_FORWARD_PTR(d->tag)) {
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("gc_copy: IS_FORWARD_PTR: return! %p\n", (size_t *) d->tag);
|
printf ("gc_copy: IS_FORWARD_PTR: return! %p -> %p\n", obj, (size_t *) d->tag);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
return (size_t *) d->tag;
|
return (size_t *) d->tag;
|
||||||
|
|
@ -1156,13 +1191,12 @@ extern size_t * gc_copy (size_t *obj) {
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("gc_copy:closure_tag; len = %zu\n", LEN(d->tag)); fflush (stdout);
|
printf ("gc_copy:closure_tag; len = %zu\n", LEN(d->tag)); fflush (stdout);
|
||||||
#endif
|
#endif
|
||||||
|
i = LEN(d->tag);
|
||||||
current += (LEN(d->tag) + 1) * sizeof (int);
|
current += (LEN(d->tag) + 1) * sizeof (int);
|
||||||
*copy = d->tag;
|
*copy = d->tag;
|
||||||
copy++;
|
copy++;
|
||||||
i = LEN(d->tag) - 1;
|
|
||||||
d->tag = (int) copy;
|
d->tag = (int) copy;
|
||||||
*copy = obj[0];
|
copy_elements (copy, obj, i);
|
||||||
copy_elements (copy, obj++, i);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ARRAY_TAG:
|
case ARRAY_TAG:
|
||||||
|
|
@ -1195,15 +1229,15 @@ extern size_t * gc_copy (size_t *obj) {
|
||||||
len1 = LEN(s->contents.tag);
|
len1 = LEN(s->contents.tag);
|
||||||
len2 = LEN(s->tag);
|
len2 = LEN(s->tag);
|
||||||
len3 = LEN(d->tag);
|
len3 = LEN(d->tag);
|
||||||
printf ("len1 = %li, len2=%li, len3 = %li\n", len1, len2, len3);
|
printf ("gc_copy:sexp_tag; len1 = %li, len2=%li, len3 = %li\n", len1, len2, len3);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
#endif
|
#endif
|
||||||
current += (LEN(s->contents.tag) + 2) * sizeof (int);
|
i = LEN(s->contents.tag);
|
||||||
|
current += (i + 2) * sizeof (int);
|
||||||
*copy = s->tag;
|
*copy = s->tag;
|
||||||
copy++;
|
copy++;
|
||||||
*copy = s->contents.tag;
|
*copy = d->tag;
|
||||||
copy++;
|
copy++;
|
||||||
i = LEN(s->contents.tag);
|
|
||||||
d->tag = (int) copy;
|
d->tag = (int) copy;
|
||||||
copy_elements (copy, obj, i);
|
copy_elements (copy, obj, i);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1223,9 +1257,9 @@ extern size_t * gc_copy (size_t *obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void gc_test_and_copy_root (size_t ** root) {
|
extern void gc_test_and_copy_root (size_t ** root) {
|
||||||
if (IS_VALID_HEAP_POINTER(*root)) {
|
if (IS_VALID_HEAP_POINTER(*root) && *root != current && *root != from_space.current && *root != to_space.current ) {
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("gc_test_and_copy_root: root %p %p\n", root, *root); fflush (stdout);
|
printf ("gc_test_and_copy_root: root %p *root %p\n", root, *root); fflush (stdout);
|
||||||
#endif
|
#endif
|
||||||
*root = gc_copy (*root);
|
*root = gc_copy (*root);
|
||||||
}
|
}
|
||||||
|
|
@ -1233,7 +1267,8 @@ extern void gc_test_and_copy_root (size_t ** root) {
|
||||||
|
|
||||||
extern void gc_root_scan_data (void) {
|
extern void gc_root_scan_data (void) {
|
||||||
size_t * p = &__start_custom_data;
|
size_t * p = &__start_custom_data;
|
||||||
while (p != &__stop_custom_data) {
|
// while (p != &__stop_custom_data) {
|
||||||
|
while (p < &__stop_custom_data) { // fix bug
|
||||||
gc_test_and_copy_root (p);
|
gc_test_and_copy_root (p);
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
|
@ -1243,25 +1278,21 @@ extern void init_pool (void) {
|
||||||
size_t space_size = SPACE_SIZE * sizeof(size_t);
|
size_t space_size = SPACE_SIZE * sizeof(size_t);
|
||||||
from_space.begin = mmap (NULL, space_size, PROT_READ | PROT_WRITE,
|
from_space.begin = mmap (NULL, space_size, PROT_READ | PROT_WRITE,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
|
||||||
to_space.begin = mmap (NULL, space_size, PROT_READ | PROT_WRITE,
|
to_space.begin = NULL;
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0);
|
if (to_space.begin == MAP_FAILED) {
|
||||||
if (to_space.begin == MAP_FAILED || from_space.begin == MAP_FAILED) {
|
|
||||||
perror ("EROOR: init_pool: mmap failed\n");
|
perror ("EROOR: init_pool: mmap failed\n");
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
from_space.current = from_space.begin;
|
from_space.current = from_space.begin;
|
||||||
from_space.end = from_space.begin + SPACE_SIZE;
|
from_space.end = from_space.begin + SPACE_SIZE;
|
||||||
from_space.size = SPACE_SIZE;
|
from_space.size = SPACE_SIZE;
|
||||||
to_space.current = to_space.begin;
|
to_space.current = NULL;
|
||||||
to_space.end = to_space.begin + SPACE_SIZE;
|
to_space.end = NULL;
|
||||||
to_space.size = SPACE_SIZE;
|
to_space.size = NULL;
|
||||||
}
|
|
||||||
|
|
||||||
static int free_pool (pool * p) {
|
|
||||||
return munmap((void *)p->begin, p->size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * gc (size_t size) {
|
static void * gc (size_t size) {
|
||||||
|
init_to_space(); // new
|
||||||
current = to_space.begin;
|
current = to_space.begin;
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("\ngc: current:%p; to_space.b =%p; to_space.e =%p; f_space.b = %p; f_space.e = %p\n",
|
printf ("\ngc: current:%p; to_space.b =%p; to_space.e =%p; f_space.b = %p; f_space.e = %p\n",
|
||||||
|
|
@ -1372,12 +1403,15 @@ static void printFromSpace (void) {
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf ("\nprintFromSpace: ERROR: bad tag %d", TAG(d->tag));
|
printf ("\nprintFromSpace: ERROR: bad tag %d", TAG(d->tag));
|
||||||
|
perror ("\nprintFromSpace: ERROR: bad tag");
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
cur += len * sizeof(int);
|
cur += len * sizeof(int);
|
||||||
printf ("len = %zu, new cur = %p\n", len, cur);
|
printf ("len = %zu, new cur = %p\n", len, cur);
|
||||||
}
|
}
|
||||||
|
printf ("\nprintFromSpace: end: the whole space is printed!\n===================\n\n");
|
||||||
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -1398,9 +1432,6 @@ extern void * alloc (size_t size) {
|
||||||
#ifdef DEBUG_PRINT
|
#ifdef DEBUG_PRINT
|
||||||
printf ("alloc: call gc: %zu\n", size); fflush (stdout);
|
printf ("alloc: call gc: %zu\n", size); fflush (stdout);
|
||||||
printFromSpace(); fflush (stdout);
|
printFromSpace(); fflush (stdout);
|
||||||
#endif
|
|
||||||
p = gc (size);
|
|
||||||
#ifdef DEBUG_PRINT
|
|
||||||
printf("gc END\n\n"); fflush (stdout);
|
printf("gc END\n\n"); fflush (stdout);
|
||||||
printFromSpace(); fflush (stdout);
|
printFromSpace(); fflush (stdout);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue