diff --git a/bigint/build/bin/testbip b/bigint/build/bin/testbip index be10a5a..7c94e48 100755 Binary files a/bigint/build/bin/testbip and b/bigint/build/bin/testbip differ diff --git a/bigint/build/lib/libbigint.a b/bigint/build/lib/libbigint.a index 631f6e5..2907fce 100644 Binary files a/bigint/build/lib/libbigint.a and b/bigint/build/lib/libbigint.a differ diff --git a/bigint/src/bigint.o b/bigint/src/bigint.o index 4e68f95..162ad9f 100644 Binary files a/bigint/src/bigint.o and b/bigint/src/bigint.o differ diff --git a/bigint/src/libbigint.a b/bigint/src/libbigint.a index 631f6e5..2907fce 100644 Binary files a/bigint/src/libbigint.a and b/bigint/src/libbigint.a differ diff --git a/bigint/tst/support.o b/bigint/tst/support.o index f5bd62d..7f7b6da 100644 Binary files a/bigint/tst/support.o and b/bigint/tst/support.o differ diff --git a/bigint/tst/testbip b/bigint/tst/testbip index be10a5a..7c94e48 100755 Binary files a/bigint/tst/testbip and b/bigint/tst/testbip differ diff --git a/bigint/tst/testbip.o b/bigint/tst/testbip.o index 8acdffd..d8aaf39 100644 Binary files a/bigint/tst/testbip.o and b/bigint/tst/testbip.o differ diff --git a/njvm.c b/njvm.c index 39feb49..639dd7e 100644 --- a/njvm.c +++ b/njvm.c @@ -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,8 +51,8 @@ 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) printf("(%i)",i); +// if (debug == 1 || bp == i) debugMenu(fp, stack, &debug, i, &bp); + if (debug == 1) printf("(%i)", i); switch (program.program[i] >> 24) { case HALT: if (debug == 1) printf("halt\n"); @@ -245,25 +260,25 @@ void execute(struct program program) { case GETF: if (debug == 1) printf("getf\n"); tempObj = pop(stack).u.objRef; - push(stack, stackSlotWithObjRef(getField(tempObj,SIGN_EXTEND(IMMEDIATE(program.program[i]))))); + push(stack, stackSlotWithObjRef(getField(tempObj, SIGN_EXTEND(IMMEDIATE(program.program[i]))))); break; case PUTF: if (debug == 1) printf("putf\t%i\n", SIGN_EXTEND(IMMEDIATE(program.program[i]))); tempObj = pop(stack).u.objRef; tempObj2 = pop(stack).u.objRef; - setField(tempObj2, SIGN_EXTEND(IMMEDIATE(program.program[i])),tempObj); + setField(tempObj2, SIGN_EXTEND(IMMEDIATE(program.program[i])), tempObj); break; case NEWA: - if(debug == 1) printf("newa\n"); + if (debug == 1) printf("newa\n"); bip.op1 = pop(stack).u.objRef; push(stack, stackSlotWithObjRef(newRecord(bigToInt()))); break; case GETFA: - if(debug == 1) printf("getfa\n"); + if (debug == 1) printf("getfa\n"); bip.op1 = pop(stack).u.objRef; tempInt = bigToInt(); tempObj = pop(stack).u.objRef; - push(stack, stackSlotWithObjRef(getField(tempObj,bigToInt()))); + push(stack, stackSlotWithObjRef(getField(tempObj, bigToInt()))); break; case PUTFA: if (debug == 1) printf("putfa\n"); @@ -271,12 +286,12 @@ void execute(struct program program) { tempObj2 = pop(stack).u.objRef; // Index bip.op1 = tempObj2; tempInt = bigToInt(); - setField(pop(stack).u.objRef, tempInt,tempObj); + setField(pop(stack).u.objRef, tempInt, tempObj); break; case GETSZ: if (debug == 1) printf("getsz\n"); tempObj = pop(stack).u.objRef; - if(IS_PRIMITIVE(tempObj)) bigFromInt(-1); + if (IS_PRIMITIVE(tempObj)) bigFromInt(-1); else bigFromInt(GET_ELEMENT_COUNT(tempObj)); push(stack, stackSlotWithObjRef(bip.res)); break; @@ -286,13 +301,13 @@ void execute(struct program program) { break; case REFEQ: if (debug == 1) printf("refeq\n"); - if(pop(stack).u.objRef == pop(stack).u.objRef) bigFromInt(true); + if (pop(stack).u.objRef == pop(stack).u.objRef) bigFromInt(true); else bigFromInt(false); push(stack, stackSlotWithObjRef(bip.res)); break; case REFNE: if (debug == 1) printf("refeq\n"); - if(pop(stack).u.objRef != pop(stack).u.objRef) bigFromInt(true); + if (pop(stack).u.objRef != pop(stack).u.objRef) bigFromInt(true); else bigFromInt(false); push(stack, stackSlotWithObjRef(bip.res)); break; @@ -305,8 +320,135 @@ void execute(struct program program) { void tests(void) { } -int main(int argc, char *argv[]) { +/* + * Garbage Collection + */ +ObjRef *heap; +int heapSizeKiB; +char *memTargetPtr; +char *freeHeapPtr; +char *halfHeapPtr; +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) +#define GET_REFS(objRef)((ObjRef *)((objRef)->data)) + +ObjRef copyObjectToFreeMem(ObjRef 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; + freeHeapPtr += size; + return oldPtr; +} + +ObjRef relocate(ObjRef orig) { + ObjRef copy; + if (orig == NULL) { + copy = NULL; + } else { + if (orig->brokenHeart == 1) { + copy = orig->forwardPointer; + } else { + copy = copyObjectToFreeMem(orig); + orig->brokenHeart = true; + orig->forwardPointer = copy; + } + } + + return copy; +} + + +void scan(void) { + char *scanPtr = memTargetPtr; + while (scanPtr < freeHeapPtr) { + ObjRef scanOr = (ObjRef) scanPtr; + + if (!IS_PRIMITIVE(scanOr)) { + 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 { + scanPtr += GET_SIZE(scanOr); + } + } +} + +void swap() { + if (memTargetPtr == (char *) heap) { + freeHeapPtr = halfHeapPtr; + memTargetPtr = halfHeapPtr; + halfHeapPtr = ((char *) heap) + (heapSizeKiB * 1024); + } else { + freeHeapPtr = ((char *) heap); + memTargetPtr = ((char *) heap); + halfHeapPtr = ((char *) heap) + ((heapSizeKiB * 1024) / 2); + } +} + +void garbageCollector() { + char *memToPurgePtr = halfHeapPtr - ((heapSizeKiB * 1024) / 2); + swap(); + + for (int i = 0; i < *stack.size; i++) { + if (stack.stack[i].isObjRef) { + stack.stack[i].u.objRef = relocate(stack.stack[i].u.objRef); + } + } + + for (int i = 0; i < *sda.size; i++) { + sda.sda[i] = relocate(sda.sda[i]); + } + + 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 = alloc(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 +479,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) { @@ -349,17 +492,22 @@ int main(int argc, char *argv[]) { return 0; } else if (strcmp(argv[i], "--stack") == 0) { i++; - // TODO: implement stack size + size = atoi(argv[i]); } else if (strcmp(argv[i], "--heap") == 0) { i++; - // TODO: implement heap size + argVheapSizeKiB = atoi(argv[i]); } else if (strcmp(argv[i], "--gcpurge") == 0) { - // TODO: implement gcpurge + purgeFlag = true; } else { sizeSDA = fromFile(argv[i], program); run = 1; } } + //heapAllocator(argVheapSizeKiB); + // Init the sda + ObjRef s[sizeSDA]; + sda.size = &sizeSDA; + sda.sda = s; } if (debug) { diff --git a/njvm.o b/njvm.o index 15cff30..57daa1f 100644 Binary files a/njvm.o and b/njvm.o differ diff --git a/objref.c b/objref.c index 7dcdf76..2e0aeb5 100644 --- a/objref.c +++ b/objref.c @@ -6,6 +6,8 @@ typedef struct ObjRef{ unsigned int size; unsigned char data[1]; + bool brokenHeart; + struct ObjRef *forwardPointer; } *ObjRef; #endif /* ifndef OBJREF diff --git a/support.o b/support.o index e0fc0d2..d48f255 100644 Binary files a/support.o and b/support.o differ