115 lines
2.6 KiB
C
115 lines
2.6 KiB
C
#ifndef GC
|
|
#define GC
|
|
#define HAS_BROKENHEART_FLAG(objRef) (((objRef)->size & 1 << (7 * sizeof(unsigned int) -1)) == 0)
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
#include "objref.c"
|
|
#include "instruktion.c"
|
|
#include "support.c"
|
|
|
|
ObjRef heap;
|
|
ObjRef freePointer;
|
|
ObjRef middle;
|
|
ObjRef start;
|
|
ObjRef end;
|
|
ObjRef finalEnd;
|
|
ObjRef scanPtr;
|
|
ObjRef tmpEnd;
|
|
|
|
unsigned int defaultHeap = 8192 * 1024;
|
|
|
|
void heapAlloc(unsigned int size){
|
|
heap = malloc(size);
|
|
if(heap == NULL){
|
|
fatalError("Not enough memory on Heap\n");
|
|
}
|
|
|
|
start = heap;
|
|
freePointer = start;
|
|
middle = (heap + (defaultHeap/2));
|
|
end = middle;
|
|
finalEnd = (middle + (defaultHeap/2));
|
|
}
|
|
|
|
void flip(void){
|
|
freePointer = end;
|
|
tmpEnd = finalEnd;
|
|
}
|
|
|
|
ObjRef copyObjToFreeMem(ObjRef obj){
|
|
ObjRef tmp = freePointer;
|
|
memcpy(tmp, obj, obj->size);
|
|
if(IS_PRIMITIVE(tmp)){
|
|
freePointer += sizeof(tmp) + tmp->size;
|
|
}else{
|
|
freePointer += sizeof(tmp) + tmp->size * sizeof(void*);
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
ObjRef rellocate(ObjRef orig){
|
|
ObjRef copy;
|
|
if (orig == NULL){
|
|
|
|
copy = NULL;
|
|
} else {
|
|
unsigned int tmp = HAS_BROKENHEART_FLAG(orig);
|
|
if (tmp){
|
|
copy = orig->forward_pointer;
|
|
} else {
|
|
copy = copyObjToFreeMem(orig);
|
|
orig->size = (1 | (1 << (7 * sizeof(unsigned int) -1)));
|
|
//SET_BROKENHEART_FLAG(orig);
|
|
orig->forward_pointer = copy;
|
|
}
|
|
}
|
|
return copy;
|
|
}
|
|
|
|
void garbageColl(void){
|
|
flip();
|
|
for(int i = 0; i < program_size; i++){
|
|
static_data_area[i] = rellocate(static_data_area[i]); // alte Objekte werden in neue akktive Halbspeicher geleitet bei relocate!
|
|
}
|
|
bip.op1 = rellocate(bip.op1);
|
|
bip.op2 = rellocate(bip.op2);
|
|
bip.res = rellocate(bip.res);
|
|
bip.rem = rellocate(bip.rem);
|
|
returnValueReg = rellocate(returnValueReg);
|
|
|
|
scan();
|
|
end = finalEnd;
|
|
}
|
|
|
|
ObjRef garbageCollectorMalloc(unsigned int size){
|
|
if((freePointer + size) > end){
|
|
garbageColl();
|
|
} else if((freePointer > finalEnd)){
|
|
fatalError("Not enough memory on Heap\n");
|
|
}
|
|
ObjRef obj = freePointer;
|
|
if(obj == NULL){
|
|
fatalError("Object is Null\n");
|
|
}
|
|
freePointer += size;
|
|
return obj;
|
|
}
|
|
|
|
|
|
void scan(void){
|
|
scanPtr = start; //Zielspeicherzeiger;
|
|
while (scanPtr < freePointer){
|
|
|
|
if (!IS_PRIMITIVE(scanPtr)){
|
|
|
|
for (int i = 0; i < GET_ELEMENT_COUNT(scanPtr); i++){
|
|
GET_REFS_PTR(scanPtr)[i] = rellocate(GET_REFS_PTR(scanPtr)[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|