Compare commits

..

7 Commits

Author SHA1 Message Date
240e93a90f +++ 2024-01-28 23:20:45 +01:00
bc41dcda4a --- 2024-01-28 23:15:34 +01:00
f62030772a ,,, 2024-01-28 23:10:28 +01:00
43663714ca ... 2024-01-28 23:06:11 +01:00
38bfd5c7d9 add heap size 2024-01-28 23:02:03 +01:00
nilspolek
f348174229 gc 2024-01-28 22:29:20 +01:00
nilspolek
bc8a037a30 gc 2024-01-28 22:26:50 +01:00
19 changed files with 161 additions and 250 deletions

View File

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

95
GC.c
View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

Binary file not shown.

Binary file not shown.

33
heap.c Normal file
View File

@@ -0,0 +1,33 @@
//
// 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 Normal file
View File

@@ -0,0 +1,12 @@
//
// 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

216
njvm.c
View File

@@ -1,3 +1,6 @@
#ifndef NJVM
#define NJVM
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -8,30 +11,15 @@
#include "debugMenu.c"
#include "bigint.h"
#include "record.c"
#include "SDA.c"
#include "GC.c"
#include "heap.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;
void version(void) {
@@ -51,7 +39,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:
@@ -320,191 +308,13 @@ void execute(struct program program) {
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[]) {
// Init the Heap
//initHeap(1000);
// Initialize the Stack
int size = SIZE;
int current = 0;
stack.size = &size;
stack.current = &current;
stack.stack = malloc(SIZE * 1024);
stack.stack = malloc(size * 1024);
if (stack.stack == NULL) {
perror("malloc");
}
@@ -528,7 +338,6 @@ 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) {
@@ -544,7 +353,7 @@ int main(int argc, char *argv[]) {
// TODO: implement stack size
} else if (strcmp(argv[i], "--heap") == 0) {
i++;
// TODO: implement heap size
initHeap(atoi(argv[i]));
} else if (strcmp(argv[i], "--gcpurge") == 0) {
// TODO: implement gcpurge
} else {
@@ -552,11 +361,6 @@ int main(int argc, char *argv[]) {
run = 1;
}
}
heapAllocator(argVheapSizeKiB);
// Init the sda
ObjRef s[sizeSDA];
sda.size = &sizeSDA;
sda.sda = s;
}
if (debug) {
@@ -575,4 +379,6 @@ int main(int argc, char *argv[]) {
printf("Error: no code file specified\n");
return 1;
}
}
}
#endif /* ifndef NJVM */

11
njvm.h
View File

@@ -1,11 +0,0 @@
//
// 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,19 +1,12 @@
#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 */

BIN
prog.bin

Binary file not shown.

View File

@@ -5,13 +5,11 @@
#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 = alloc(objSize)) == NULL){
if((record = my_malloc(objSize)) == NULL){
perror("malloc");
}
record->size = MSB;
@@ -49,7 +47,7 @@ void setField(ObjRef arr, int point, ObjRef value){
else
size = sizeof(*value) + (GET_ELEMENT_COUNT(value) * sizeof(void *));
}
if((GET_REFS_PTR(arr)[point] = malloc(size)) == NULL) perror("malloc");
if((GET_REFS_PTR(arr)[point] = my_malloc(size)) == NULL) perror("malloc");
GET_REFS_PTR(arr)[point] ->size = size;
* (ObjRef *)GET_REFS_PTR(arr)[point]->data = value;
}

View File

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

View File

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

BIN
support.o Normal file

Binary file not shown.