#ifndef GC #define GC #define HAS_BROKENHEART_FLAG(objRef) (((objRef)->size & 1 << (7 * sizeof(unsigned int) -1)) == 0) #include #include #include #include #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