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
17 changed files with 242 additions and 101 deletions

View File

@@ -5,7 +5,8 @@ set(CMAKE_C_STANDARD 99)
add_compile_options(-g -Wall -pedantic)
add_executable(njvm njvm.c)
add_executable(njvm njvm.c
njvm.h)
# Include directories for njvm executable
target_include_directories(njvm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include)

95
GC.c
View File

@@ -1,99 +1,14 @@
#ifndef GC
#define GC
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "stackslot.c"
#include "stack.c"
#include "bigint.h"
#include <stdbool.h>
#include "objref.c"
#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;
#include "support.c"
#include "bigint.h"
//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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

205
njvm.c
View File

@@ -8,14 +8,29 @@
#include "debugMenu.c"
#include "bigint.h"
#include "record.c"
#include "GC.c"
#include "SDA.c"
// Debug
int debug = 0;
// Purge Flag
int purgeFlag = false;
// Heap Size
int argVheapSizeKiB = 8192;
// Program
struct program program;
// SDA
struct sda sda;
// Stack
struct stack stack;
#define SIZE 10000
//Register
struct stack reg;
unsigned fp;
@@ -36,7 +51,7 @@ void execute(struct program program) {
ObjRef tempObj2;
int tempInt;
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);
switch (program.program[i] >> 24) {
case HALT:
@@ -305,8 +320,184 @@ void execute(struct program program) {
void tests(void) {
}
int main(int argc, char *argv[]) {
/*
* 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[]) {
// Init the Heap
//initHeap(1000);
// Initialize the Stack
int size = SIZE;
@@ -337,6 +528,7 @@ int main(int argc, char *argv[]) {
int run = 0;
int sizeSDA;
if (argc > 1) {
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--debug") == 0) {
@@ -360,6 +552,11 @@ int main(int argc, char *argv[]) {
run = 1;
}
}
heapAllocator(argVheapSizeKiB);
// Init the sda
ObjRef s[sizeSDA];
sda.size = &sizeSDA;
sda.sda = s;
}
if (debug) {
@@ -378,4 +575,4 @@ int main(int argc, char *argv[]) {
printf("Error: no code file specified\n");
return 1;
}
}
}

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

View File

@@ -5,11 +5,13 @@
#define RECORD
#include "stackslot.c"
#include "instruktion.c"
#include "njvm.h"
ObjRef newRecord(int size){
ObjRef record;
unsigned int objSize;
objSize = sizeof(*record) + (size * sizeof(void *));
if((record = malloc(objSize)) == NULL){
if((record = alloc(objSize)) == NULL){
perror("malloc");
}
record->size = MSB;

View File

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

BIN
support.o

Binary file not shown.