Compare commits
5 Commits
master
...
c3629d7150
| Author | SHA1 | Date | |
|---|---|---|---|
| c3629d7150 | |||
| 3c3d2716a5 | |||
|
|
35f051b5da | ||
|
|
221a08e7dc | ||
|
|
84dcb63ea7 |
@@ -5,7 +5,8 @@ set(CMAKE_C_STANDARD 99)
|
|||||||
|
|
||||||
add_compile_options(-g -Wall -pedantic)
|
add_compile_options(-g -Wall -pedantic)
|
||||||
|
|
||||||
add_executable(njvm njvm.c)
|
add_executable(njvm njvm.c
|
||||||
|
njvm.h)
|
||||||
|
|
||||||
# Include directories for njvm executable
|
# Include directories for njvm executable
|
||||||
target_include_directories(njvm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include)
|
target_include_directories(njvm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bigint/build/include)
|
||||||
|
|||||||
95
GC.c
95
GC.c
@@ -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 64
|
|
||||||
|
|
||||||
//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.
Binary file not shown.
@@ -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.
Binary file not shown.
203
njvm.c
203
njvm.c
@@ -8,14 +8,29 @@
|
|||||||
#include "debugMenu.c"
|
#include "debugMenu.c"
|
||||||
#include "bigint.h"
|
#include "bigint.h"
|
||||||
#include "record.c"
|
#include "record.c"
|
||||||
#include "GC.c"
|
#include "SDA.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;
|
||||||
|
|
||||||
@@ -36,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:
|
||||||
@@ -305,8 +320,184 @@ void execute(struct program program) {
|
|||||||
void tests(void) {
|
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
|
// Initialize the Stack
|
||||||
int size = SIZE;
|
int size = SIZE;
|
||||||
@@ -337,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) {
|
||||||
@@ -360,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) {
|
||||||
|
|||||||
11
njvm.h
Normal file
11
njvm.h
Normal 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
|
||||||
9
objref.c
9
objref.c
@@ -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 */
|
||||||
|
|||||||
4
record.c
4
record.c
@@ -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 = malloc(objSize)) == NULL){
|
if((record = alloc(objSize)) == NULL){
|
||||||
perror("malloc");
|
perror("malloc");
|
||||||
}
|
}
|
||||||
record->size = MSB;
|
record->size = MSB;
|
||||||
|
|||||||
@@ -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 "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 = 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
|
||||||
Reference in New Issue
Block a user