Compare commits

..

5 Commits

Author SHA1 Message Date
c3629d7150 add gc 2024-01-28 17:32:30 +01:00
3c3d2716a5 Revert "testing"
This reverts commit 221a08e7
2024-01-28 17:03:10 +01:00
nilspolek
35f051b5da gc 2024-01-28 16:45:50 +01:00
nilspolek
221a08e7dc testing 2024-01-28 10:54:17 +01:00
nilspolek
84dcb63ea7 testing 2024-01-28 10:51:57 +01:00
19 changed files with 250 additions and 161 deletions

View File

@@ -14,9 +14,7 @@ target_include_directories(njvm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build
# Add the library # Add the library
add_library(bigint STATIC ${CMAKE_SOURCE_DIR}/bigint/src/bigint.c add_library(bigint STATIC ${CMAKE_SOURCE_DIR}/bigint/src/bigint.c
support.c support.c
GC.c GC.c)
heap.c
heap.h)
# Include directories for the bigint library # Include directories for the bigint library
target_include_directories(bigint PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include) target_include_directories(bigint PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include)

95
GC.c
View File

@@ -1,99 +1,14 @@
#ifndef GC #ifndef GC
#define GC #define GC
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "stackslot.c" #include <stdbool.h>
#include "stack.c" #include "objref.c"
#include "bigint.h"
#include "instruktion.c" #include "instruktion.c"
#include "record.c" #include "support.c"
#include "SDA.c" #include "bigint.h"
typedef struct {
unsigned int freiZeiger;
unsigned int size;
unsigned char *data;
} *heapPartRef;
// SDA
struct sda sda;
// Stack
struct stack stack;
#define SIZE 1000;
//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 #endif

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -5,12 +5,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include "support.h" #include "support.h"
typedef struct { typedef struct ObjRef{
unsigned int size; /* byte count of payload data */ bool brokenHeart;
unsigned char data[1]; /* payload data, size as needed */ struct ObjRef *forward_pointer;
unsigned int size;
unsigned char data[1];
} *ObjRef; } *ObjRef;

Binary file not shown.

Binary file not shown.

33
heap.c
View File

@@ -1,33 +0,0 @@
//
// Created by Elias Bennour on 28.01.24.
//
#ifndef HEAP
#define HEAP
#include <stdlib.h>
#include <stdio.h>
int maxHeapSize = 8192 * 1024;
void* my_malloc(size_t size) {
static size_t total_allocated = 0;
if (total_allocated + size > maxHeapSize) {
perror("Memory limit exceeded\n");
exit(1);
}
void* ptr = malloc(size);
if (ptr != NULL) {
total_allocated += size;
}
return ptr;
}
void initHeap(int size) {
maxHeapSize = size;
}
#endif //NINJA_NJVM_H

12
heap.h
View File

@@ -1,12 +0,0 @@
//
// Created by Elias Bennour on 28.01.24.
//
#ifndef NINJA_HEAP_H
#define NINJA_HEAP_H
#include <stdlib.h>
void* my_malloc(size_t size);
#endif //NINJA_HEAP_H

214
njvm.c
View File

@@ -1,6 +1,3 @@
#ifndef NJVM
#define NJVM
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -11,15 +8,30 @@
#include "debugMenu.c" #include "debugMenu.c"
#include "bigint.h" #include "bigint.h"
#include "record.c" #include "record.c"
#include "GC.c" #include "SDA.c"
#include "heap.c"
// Debug // Debug
int debug = 0; int debug = 0;
// Purge Flag
int purgeFlag = false;
// Heap Size
int argVheapSizeKiB = 8192;
// Program // Program
struct program program; struct program program;
// SDA
struct sda sda;
// Stack
struct stack stack;
#define SIZE 10000
//Register
struct stack reg;
unsigned fp; unsigned fp;
void version(void) { void version(void) {
@@ -39,7 +51,7 @@ void execute(struct program program) {
ObjRef tempObj2; ObjRef tempObj2;
int tempInt; int tempInt;
for (i = 0; i < *program.size; ++i) { for (i = 0; i < *program.size; ++i) {
if (debug == 1 || bp == i) debugMenu(fp, stack, &debug, i, &bp); //if (debug == 1 || bp == i) debugMenu(fp, stack, &debug, i, &bp);
if(debug == 1) printf("(%i)",i); if(debug == 1) printf("(%i)",i);
switch (program.program[i] >> 24) { switch (program.program[i] >> 24) {
case HALT: case HALT:
@@ -308,13 +320,191 @@ void execute(struct program program) {
void tests(void) { void tests(void) {
} }
/*
* Garbage Collection
*/
ObjRef *heap;
int heapSizeKiB;
char *memTargetPtr; //zielspeicherzeiger
char *freeHeapPtr; //freizeiger
char *halfHeapPtr; //halbspeicherende
int gcCount = 0;
#define MSB (1 << (8 * sizeof(unsigned int) - 1))
#define IS_PRIMITIVE(objRef) (((objRef)->size & MSB) == 0)
#define GET_SIZE(objRef)((objRef)->size& ~MSB) //Gets the size of an ObjRef
#define GET_REFS(objRef)((ObjRef *)((objRef)->data)) //Pointer on first ObjRef in Object
ObjRef copyObjectToFreeMem(ObjRef orig) {
//printf("%s%d\n", "Size in CpyObj: ", GET_SIZE(orig) );
int size;
if (IS_PRIMITIVE(orig)) {
size = GET_SIZE(orig);
} else {
size = sizeof(void *) + sizeof(unsigned int) + sizeof(bool) + GET_SIZE(orig) * sizeof(ObjRef *);
}
memcpy(freeHeapPtr, orig, size);
ObjRef oldPtr = (ObjRef) freeHeapPtr;
//printf("%s%d\n","size after memcpy ", GET_SIZE(oldPtr));
//printf("%s%d\n","actual Size: ", size);
//oldPtr->size = size;
freeHeapPtr += size;
return oldPtr;
}
ObjRef relocate(ObjRef orig) {
/* if (orig == NULL) {
printf("%s\n", "null");
} else {
printf("%s%d\n","Size in relocate ", GET_SIZE(orig));
}
*/
ObjRef copy;
if (orig == NULL) {
/* relocate(nil) = nil */
copy = NULL;
} else {
if (orig->brokenHeart == 1) {
/* Objekt ist bereits kopiert */
copy = orig->forwardPointer;
//copy->size =orig->size;
//printf("%s\n", "already copied");
} else {
/* Objekt muss noch kopiert werden*/
copy = copyObjectToFreeMem(orig);
orig->brokenHeart = true;
orig->forwardPointer = copy;
}
}
return copy;
}
void scan(void) {
char *scanPtr = memTargetPtr;
while (scanPtr < freeHeapPtr) {
/* es gibt noch Objekte, die
* gescannt werden müssen.
*/ ObjRef scanOr = (ObjRef) scanPtr;
// printf("%d\n", GET_SIZE(scanOr));
if (!IS_PRIMITIVE(scanOr)) {
/* Ist ein Verbundobjekt */
for (int i = 0; i < GET_SIZE(scanOr); i++) {
GET_REFS(scanOr)[i] = relocate(GET_REFS(scanOr)[i]);
}
scanPtr += sizeof(bool) + (GET_SIZE(scanOr) * sizeof(ObjRef *)) + sizeof(unsigned int) + sizeof(void *);
} else {
//printf("%s %d\n", "is primitive, size: ", GET_SIZE(scanOr));
scanPtr += GET_SIZE(scanOr);
}
}
}
void swap() {
if (memTargetPtr == (char *) heap) {
//printf("%s\n", "swapped to second half");
freeHeapPtr = halfHeapPtr;
memTargetPtr = halfHeapPtr;
halfHeapPtr = ((char *) heap) + (heapSizeKiB * 1024);
} else {
//printf("%s\n", "swapped to first half");
freeHeapPtr = ((char *) heap);
memTargetPtr = ((char *) heap);
halfHeapPtr = ((char *) heap) + ((heapSizeKiB * 1024) / 2);
}
}
void garbageCollector() {
char *memToPurgePtr = halfHeapPtr - ((heapSizeKiB * 1024) / 2);
swap();
//printf("%s\n", "stack");
for (int i = 0; i < stack.current; i++) {
if (stack.stack[i].isObjRef) {
stack.stack[i].u.objRef = relocate(stack.stack[i].u.objRef);
}
}
//printf("%s\n", "globals");
for (int i = 0; i < sda.size; i++) {
sda.sda[i] = relocate(sda.sda[i]);
}
//printf("%s\n", "retVal");
//returnValue = relocate(returnValue);
//printf("%s\n", "op1");
bip.op1 = relocate(bip.op1);
ObjRef b = bip.op1;
if(b!= NULL)
//printf("%d\n", GET_SIZE(b));
//printf("%s\n", "op2");
bip.op2 = relocate(bip.op2);
b = bip.op2;
if(b!= NULL)
//printf("%d\n", GET_SIZE(b));
//printf("%s\n", "res");
bip.res = relocate(bip.res);
b = bip.res;
if(b!= NULL)
//printf("%d\n", GET_SIZE(b));
//printf("%s\n", "rem");
bip.rem = relocate(bip.rem);
b = bip.rem;
if(b!= NULL)
//printf("%d\n", GET_SIZE(b));
scan();
if (purgeFlag) {
memset(memToPurgePtr, 0, heapSizeKiB * 1024 / 2);
}
gcCount++;
}
ObjRef alloc(unsigned int size) {
if (freeHeapPtr + size > halfHeapPtr) {
garbageCollector();
if (freeHeapPtr + size > halfHeapPtr) {
fprintf(stderr, "Heap is full\n");
exit(1);
}
}
ObjRef or;
or = (ObjRef) freeHeapPtr;
freeHeapPtr = freeHeapPtr + size;
return or;
}
void heapAllocator(int n) {
heapSizeKiB = n;
if ((heap = malloc(n * 1024)) == NULL) {
perror("malloc");
exit(1);
}
memTargetPtr = (char *) heap;
freeHeapPtr = memTargetPtr;
halfHeapPtr = (memTargetPtr + (n * 1024) / 2);
}
/*
* Main
*/
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
// Init the Heap
//initHeap(1000);
// Initialize the Stack // Initialize the Stack
int size = SIZE; int size = SIZE;
int current = 0; int current = 0;
stack.size = &size; stack.size = &size;
stack.current = &current; stack.current = &current;
stack.stack = malloc(size * 1024); stack.stack = malloc(SIZE * 1024);
if (stack.stack == NULL) { if (stack.stack == NULL) {
perror("malloc"); perror("malloc");
} }
@@ -338,6 +528,7 @@ int main(int argc, char *argv[]) {
int run = 0; int run = 0;
int sizeSDA; int sizeSDA;
if (argc > 1) { if (argc > 1) {
for (int i = 1; i < argc; ++i) { for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--debug") == 0) { if (strcmp(argv[i], "--debug") == 0) {
@@ -353,7 +544,7 @@ int main(int argc, char *argv[]) {
// TODO: implement stack size // TODO: implement stack size
} else if (strcmp(argv[i], "--heap") == 0) { } else if (strcmp(argv[i], "--heap") == 0) {
i++; i++;
initHeap(atoi(argv[i]) * 1024); // TODO: implement heap size
} else if (strcmp(argv[i], "--gcpurge") == 0) { } else if (strcmp(argv[i], "--gcpurge") == 0) {
// TODO: implement gcpurge // TODO: implement gcpurge
} else { } else {
@@ -361,6 +552,11 @@ int main(int argc, char *argv[]) {
run = 1; run = 1;
} }
} }
heapAllocator(argVheapSizeKiB);
// Init the sda
ObjRef s[sizeSDA];
sda.size = &sizeSDA;
sda.sda = s;
} }
if (debug) { if (debug) {
@@ -380,5 +576,3 @@ int main(int argc, char *argv[]) {
return 1; return 1;
} }
} }
#endif /* ifndef NJVM */

11
njvm.h Normal file
View File

@@ -0,0 +1,11 @@
//
// Created by Elias Bennour on 28.01.24.
//
#include "objref.c"
#ifndef NINJA_NJVM_H
#define NINJA_NJVM_H
ObjRef alloc(unsigned int size);
#endif //NINJA_NJVM_H

BIN
njvm.o

Binary file not shown.

View File

@@ -1,12 +1,19 @@
#ifndef OBJREF #ifndef OBJREF
#define OBJREF #define OBJREF
#include <stdbool.h> #include <stdbool.h>
typedef struct ObjRef{ typedef struct ObjRef{
// if brkokenHeart and forward_pointer added at this point bip throws errors
bool brokenHeart;
struct ObjRef *forwardPointer;
unsigned int size; unsigned int size;
unsigned char data[1]; unsigned char data[1];
} *ObjRef; } *ObjRef;
typedef struct{
unsigned char brokenHeart;
ObjRef forward_pointer;
} *ObjRefGC;
#endif /* ifndef OBJREF #endif /* ifndef OBJREF
#define OBJREF */ #define OBJREF */

BIN
prog.bin

Binary file not shown.

View File

@@ -5,11 +5,13 @@
#define RECORD #define RECORD
#include "stackslot.c" #include "stackslot.c"
#include "instruktion.c" #include "instruktion.c"
#include "njvm.h"
ObjRef newRecord(int size){ ObjRef newRecord(int size){
ObjRef record; ObjRef record;
unsigned int objSize; unsigned int objSize;
objSize = sizeof(*record) + (size * sizeof(void *)); objSize = sizeof(*record) + (size * sizeof(void *));
if((record = my_malloc(objSize)) == NULL){ if((record = alloc(objSize)) == NULL){
perror("malloc"); perror("malloc");
} }
record->size = MSB; record->size = MSB;
@@ -47,7 +49,7 @@ void setField(ObjRef arr, int point, ObjRef value){
else else
size = sizeof(*value) + (GET_ELEMENT_COUNT(value) * sizeof(void *)); size = sizeof(*value) + (GET_ELEMENT_COUNT(value) * sizeof(void *));
} }
if((GET_REFS_PTR(arr)[point] = my_malloc(size)) == NULL) perror("malloc"); if((GET_REFS_PTR(arr)[point] = malloc(size)) == NULL) perror("malloc");
GET_REFS_PTR(arr)[point] ->size = size; GET_REFS_PTR(arr)[point] ->size = size;
* (ObjRef *)GET_REFS_PTR(arr)[point]->data = value; * (ObjRef *)GET_REFS_PTR(arr)[point]->data = value;
} }

View File

@@ -4,7 +4,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "objref.c" #include "objref.c"
#include "heap.h"
typedef int Object; typedef int Object;
@@ -20,7 +19,7 @@ typedef struct {
ObjRef getIntObj(int val) { ObjRef getIntObj(int val) {
ObjRef intObject; ObjRef intObject;
unsigned int objSize = sizeof(ObjRef) + sizeof(int); unsigned int objSize = sizeof(ObjRef) + sizeof(int);
if ((intObject = my_malloc(objSize)) == NULL) { if ((intObject = malloc(objSize)) == NULL) {
perror("malloc"); perror("malloc");
} }
*(int *) intObject->data = val; *(int *) intObject->data = val;
@@ -48,7 +47,7 @@ void setValIntObj(ObjRef iref, int val) {
StackSlot stackSlotWithObjRef(ObjRef val) { StackSlot stackSlotWithObjRef(ObjRef val) {
StackSlot *stackSlot; StackSlot *stackSlot;
stackSlot = my_malloc(sizeof(StackSlot)); stackSlot = malloc(sizeof(StackSlot));
if(stackSlot == NULL) perror("malloc"); if(stackSlot == NULL) perror("malloc");
stackSlot->isObjRef = true; stackSlot->isObjRef = true;
stackSlot->u.objRef = val; stackSlot->u.objRef = val;
@@ -57,7 +56,7 @@ StackSlot stackSlotWithObjRef(ObjRef val) {
StackSlot stackSlotWitchNumber(int val) { StackSlot stackSlotWitchNumber(int val) {
StackSlot *stackSlot; StackSlot *stackSlot;
stackSlot = my_malloc(sizeof(StackSlot)); stackSlot = malloc(sizeof(StackSlot));
if(stackSlot == NULL) perror("malloc"); if(stackSlot == NULL) perror("malloc");
stackSlot->isObjRef = false; stackSlot->isObjRef = false;
stackSlot->u.number = val; stackSlot->u.number = val;

View File

@@ -1,9 +1,12 @@
#ifndef SUPPORT_C
#define SUPPORT_C
#include "support.h" #include "support.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "objref.c" #include "objref.c"
#include "heap.h" #include "njvm.h"
void fatalError(char *msg){ void fatalError(char *msg){
printf("Fatal error: %s\n", msg); printf("Fatal error: %s\n", msg);
@@ -13,7 +16,7 @@ void fatalError(char *msg){
void * newPrimObject(int dataSize) { void * newPrimObject(int dataSize) {
ObjRef bigObjRef; ObjRef bigObjRef;
bigObjRef = my_malloc(sizeof(unsigned int) + bigObjRef = alloc(sizeof(unsigned int) +
dataSize * sizeof(unsigned char)); dataSize * sizeof(unsigned char));
if (bigObjRef == NULL) { if (bigObjRef == NULL) {
fatalError("newPrimObject() got no memory"); fatalError("newPrimObject() got no memory");
@@ -26,3 +29,5 @@ void * getPrimObjectDataPointer(void * obj){
ObjRef oo = ((ObjRef) (obj)); ObjRef oo = ((ObjRef) (obj));
return oo->data; return oo->data;
} }
#endif

BIN
support.o

Binary file not shown.