njvm/GC.c
2024-01-27 18:32:29 +01:00

100 lines
2.7 KiB
C

#ifndef GC
#define GC
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stackslot.c"
#include "stack.c"
#include "bigint.h"
#include "instruktion.c"
#include "record.c"
#include "SDA.c"
typedef struct {
unsigned int freiZeiger;
unsigned int size;
unsigned char *data;
} *heapPartRef;
// SDA
struct sda sda;
// Stack
struct stack stack;
#define SIZE 64
//Register
struct stack reg;
heapPartRef primary;
heapPartRef secondary;
unsigned int heapSize;
void initHeap(int size){
heapSize = 2 * sizeof (unsigned int) + size;
if ((primary = malloc(heapSize)) == NULL) perror("malloc");
if ((secondary = malloc(heapSize)) == NULL) perror("malloc");
}
// nimmt obj und copier es in den secondary Speicher
void copy(ObjRef obj){
if(obj->brokenHeart == true) return;
obj->brokenHeart = true;
if (IS_PRIMITIVE(obj)){
if(obj->size > secondary->size-secondary->freiZeiger) perror("Heap is to Small");
obj->forward_pointer = memcpy((void *) secondary->data[secondary->freiZeiger], obj, obj->size);
secondary->freiZeiger += obj->size;
} else {
if(sizeof(*obj) + (GET_ELEMENT_COUNT(obj) * sizeof(void *)) > secondary->size-secondary->freiZeiger) perror("Heap is to Small");
GET_ELEMENT_COUNT(obj);
obj->forward_pointer = memcpy((void *) secondary->data[secondary->freiZeiger], obj, sizeof(*obj) + (GET_ELEMENT_COUNT(obj) * sizeof(void *)));
secondary->freiZeiger += sizeof(*obj) + (GET_ELEMENT_COUNT(obj) * sizeof(void *));
for (int i = 0; i < GET_ELEMENT_COUNT(obj); ++i) {
copy(getField(obj,i));
}
}
}
void runGC(){
int rootSize = *sda.size + *reg.size + *stack.size + 4;
ObjRef* rootObjs = malloc(sizeof(ObjRef) * rootSize);
if(rootObjs == NULL) perror("malloc");
int counter = 0;
//Bip
rootObjs[0] = bip.op1;
rootObjs[counter++] = bip.op2;
rootObjs[counter++] = bip.res;
rootObjs[counter++] = bip.rem;
//SDA
for (int i = 0; i < *sda.size; ++i) {
rootObjs[counter++] = sda.sda[i];
}
//REG
for (int i = 0; i < *reg.size; ++i) {
rootObjs[counter++] = reg.stack[i].u.objRef;
}
//STACK
for (int i = 0; i < *stack.size; ++i) {
rootObjs[counter++] = stack.stack[i].u.objRef;
}
for (int i = 0; i < rootSize; ++i) {
if(rootObjs[i] == NULL) continue;
copy(rootObjs[i]);
}
heapPartRef temp = primary;
primary = secondary;
secondary = temp;
}
void *alloc(size_t size){
if(primary->size-primary->freiZeiger < size){
runGC();
}
primary->freiZeiger += size;
return (void *) primary->data[primary->freiZeiger - size];
}
#endif