njvm/GC.c
2024-01-26 17:01:07 +01:00

78 lines
1.8 KiB
C

#include <string.h>
typedef struct {
unsigned int size;
unsigned int current;
unsigned char data[1];
} heapPart;
typedef struct {
heapPart *primary;
heapPart *secondary;
unsigned int size;
unsigned int current;
} heap;
void scan(heap *h) {
heapPart *part = h->primary;
unsigned int i;
for (i = 0; i < h->current; i++) {
unsigned int j;
for (j = 0; j < part->current; j++) {
void *p = *(void **) (part->data + j);
if (p >= part->data && p < part->data + part->size) {
*(void **) (part->data + j) = h->secondary + h->current;
memcpy(h->secondary + h->current, p, sizeof(void *));
h->current++;
}
}
part++;
}
}
void collect(heap *h) {
scan(h);
heapPart *tmp = h->primary;
h->primary = h->secondary;
h->secondary = tmp;
h->current = 0;
}
void *alloc(heap *h, unsigned int size) {
if (h->current == h->size) {
collect(h);
}
heapPart *part = h->primary + h->current;
if (part->current + size > part->size) {
collect(h);
part = h->primary + h->current;
}
void *p = part->data + part->current;
part->current += size;
return p;
}
void *reallocate(heap *h, void *p, unsigned int size) {
if (p == NULL) {
return alloc(h, size);
}
heapPart *part = h->primary;
unsigned int i;
for (i = 0; i < h->current; i++) {
if (p >= part->data && p < part->data + part->size) {
break;
}
part++;
}
if (i == h->current) {
return NULL;
}
if (size <= part->size) {
return p;
}
void *newP = alloc(h, size);
if (newP == NULL) {
return NULL;
}
memcpy(newP, p, part->size);
return newP;
}