...
This commit is contained in:
parent
958c383f85
commit
f4b1ce03c5
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
180
njvm.c
180
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,8 +51,8 @@ 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:
|
||||||
if (debug == 1) printf("halt\n");
|
if (debug == 1) printf("halt\n");
|
||||||
@ -245,25 +260,25 @@ void execute(struct program program) {
|
|||||||
case GETF:
|
case GETF:
|
||||||
if (debug == 1) printf("getf\n");
|
if (debug == 1) printf("getf\n");
|
||||||
tempObj = pop(stack).u.objRef;
|
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;
|
break;
|
||||||
case PUTF:
|
case PUTF:
|
||||||
if (debug == 1) printf("putf\t%i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
if (debug == 1) printf("putf\t%i\n", SIGN_EXTEND(IMMEDIATE(program.program[i])));
|
||||||
tempObj = pop(stack).u.objRef;
|
tempObj = pop(stack).u.objRef;
|
||||||
tempObj2 = 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;
|
break;
|
||||||
case NEWA:
|
case NEWA:
|
||||||
if(debug == 1) printf("newa\n");
|
if (debug == 1) printf("newa\n");
|
||||||
bip.op1 = pop(stack).u.objRef;
|
bip.op1 = pop(stack).u.objRef;
|
||||||
push(stack, stackSlotWithObjRef(newRecord(bigToInt())));
|
push(stack, stackSlotWithObjRef(newRecord(bigToInt())));
|
||||||
break;
|
break;
|
||||||
case GETFA:
|
case GETFA:
|
||||||
if(debug == 1) printf("getfa\n");
|
if (debug == 1) printf("getfa\n");
|
||||||
bip.op1 = pop(stack).u.objRef;
|
bip.op1 = pop(stack).u.objRef;
|
||||||
tempInt = bigToInt();
|
tempInt = bigToInt();
|
||||||
tempObj = pop(stack).u.objRef;
|
tempObj = pop(stack).u.objRef;
|
||||||
push(stack, stackSlotWithObjRef(getField(tempObj,bigToInt())));
|
push(stack, stackSlotWithObjRef(getField(tempObj, bigToInt())));
|
||||||
break;
|
break;
|
||||||
case PUTFA:
|
case PUTFA:
|
||||||
if (debug == 1) printf("putfa\n");
|
if (debug == 1) printf("putfa\n");
|
||||||
@ -271,12 +286,12 @@ void execute(struct program program) {
|
|||||||
tempObj2 = pop(stack).u.objRef; // Index
|
tempObj2 = pop(stack).u.objRef; // Index
|
||||||
bip.op1 = tempObj2;
|
bip.op1 = tempObj2;
|
||||||
tempInt = bigToInt();
|
tempInt = bigToInt();
|
||||||
setField(pop(stack).u.objRef, tempInt,tempObj);
|
setField(pop(stack).u.objRef, tempInt, tempObj);
|
||||||
break;
|
break;
|
||||||
case GETSZ:
|
case GETSZ:
|
||||||
if (debug == 1) printf("getsz\n");
|
if (debug == 1) printf("getsz\n");
|
||||||
tempObj = pop(stack).u.objRef;
|
tempObj = pop(stack).u.objRef;
|
||||||
if(IS_PRIMITIVE(tempObj)) bigFromInt(-1);
|
if (IS_PRIMITIVE(tempObj)) bigFromInt(-1);
|
||||||
else bigFromInt(GET_ELEMENT_COUNT(tempObj));
|
else bigFromInt(GET_ELEMENT_COUNT(tempObj));
|
||||||
push(stack, stackSlotWithObjRef(bip.res));
|
push(stack, stackSlotWithObjRef(bip.res));
|
||||||
break;
|
break;
|
||||||
@ -286,13 +301,13 @@ void execute(struct program program) {
|
|||||||
break;
|
break;
|
||||||
case REFEQ:
|
case REFEQ:
|
||||||
if (debug == 1) printf("refeq\n");
|
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);
|
else bigFromInt(false);
|
||||||
push(stack, stackSlotWithObjRef(bip.res));
|
push(stack, stackSlotWithObjRef(bip.res));
|
||||||
break;
|
break;
|
||||||
case REFNE:
|
case REFNE:
|
||||||
if (debug == 1) printf("refeq\n");
|
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);
|
else bigFromInt(false);
|
||||||
push(stack, stackSlotWithObjRef(bip.res));
|
push(stack, stackSlotWithObjRef(bip.res));
|
||||||
break;
|
break;
|
||||||
@ -305,8 +320,135 @@ 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;
|
||||||
|
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
|
// Initialize the Stack
|
||||||
int size = SIZE;
|
int size = SIZE;
|
||||||
@ -337,6 +479,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) {
|
||||||
@ -349,17 +492,22 @@ int main(int argc, char *argv[]) {
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(argv[i], "--stack") == 0) {
|
} else if (strcmp(argv[i], "--stack") == 0) {
|
||||||
i++;
|
i++;
|
||||||
// TODO: implement stack size
|
size = atoi(argv[i]);
|
||||||
} else if (strcmp(argv[i], "--heap") == 0) {
|
} else if (strcmp(argv[i], "--heap") == 0) {
|
||||||
i++;
|
i++;
|
||||||
// TODO: implement heap size
|
argVheapSizeKiB = atoi(argv[i]);
|
||||||
} else if (strcmp(argv[i], "--gcpurge") == 0) {
|
} else if (strcmp(argv[i], "--gcpurge") == 0) {
|
||||||
// TODO: implement gcpurge
|
purgeFlag = true;
|
||||||
} else {
|
} else {
|
||||||
sizeSDA = fromFile(argv[i], program);
|
sizeSDA = fromFile(argv[i], program);
|
||||||
run = 1;
|
run = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//heapAllocator(argVheapSizeKiB);
|
||||||
|
// Init the sda
|
||||||
|
ObjRef s[sizeSDA];
|
||||||
|
sda.size = &sizeSDA;
|
||||||
|
sda.sda = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
|||||||
2
objref.c
2
objref.c
@ -6,6 +6,8 @@
|
|||||||
typedef struct ObjRef{
|
typedef struct ObjRef{
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
unsigned char data[1];
|
unsigned char data[1];
|
||||||
|
bool brokenHeart;
|
||||||
|
struct ObjRef *forwardPointer;
|
||||||
} *ObjRef;
|
} *ObjRef;
|
||||||
|
|
||||||
#endif /* ifndef OBJREF
|
#endif /* ifndef OBJREF
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user