...
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 "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) {
|
||||
|
||||
2
objref.c
2
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user