From: bdemsky Date: Wed, 9 May 2007 17:36:07 +0000 (+0000) Subject: check in changes for tag support X-Git-Tag: preEdgeChange~594 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b0a3fca785f72dc0a4bd45004e8d90c907162b6f;p=IRC.git check in changes for tag support --- diff --git a/Robust/src/ClassLibrary/Object.java b/Robust/src/ClassLibrary/Object.java index a972bfd2..6fbd8047 100644 --- a/Robust/src/ClassLibrary/Object.java +++ b/Robust/src/ClassLibrary/Object.java @@ -3,6 +3,9 @@ public class Object { private int cachedCode; private boolean cachedHash; + /* DO NOT USE ANY OF THESE - THEY ARE FOR IMPLEMENTING TAGS */ + private Object tags; + public int hashCode() { if (!cachedHash) { cachedCode=nativehashCode(); diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 5d49ef3b..e744e1f2 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -100,6 +100,11 @@ public class BuildCode { (state.getArrayNumber( (new TypeDescriptor(typeutil.getClass(TypeUtil.StringClass))).makeArray(state))+state.numClasses())); + outstructs.println("#define OBJECTARRAYTYPE "+ + (state.getArrayNumber( + (new TypeDescriptor(typeutil.getClass(TypeUtil.ObjectClass))).makeArray(state))+state.numClasses())); + + outstructs.println("#define STRINGTYPE "+typeutil.getClass(TypeUtil.StringClass).getId()); outstructs.println("#define CHARARRAYTYPE "+ (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.CHAR)).makeArray(state))+state.numClasses())); @@ -111,9 +116,13 @@ public class BuildCode { (state.getArrayNumber((new TypeDescriptor(TypeDescriptor.BYTE)).makeArray(state).makeArray(state))+state.numClasses())); outstructs.println("#define NUMCLASSES "+state.numClasses()); - if (state.TASK) + if (state.TASK) { outstructs.println("#define STARTUPTYPE "+typeutil.getClass(TypeUtil.StartupClass).getId()); - + outstructs.println("#define TAGTYPE "+typeutil.getClass(TypeUtil.TagClass).getId()); + outstructs.println("#define TAGARRAYTYPE "+ + (state.getArrayNumber(new TypeDescriptor(typeutil.getClass(TypeUtil.TagClass)).makeArray(state))+state.numClasses())); + } + // Output the C class declarations // These could mutually reference each other if (state.THREAD) @@ -159,6 +168,7 @@ public class BuildCode { outtask.println("struct taskdescriptor {"); outtask.println("void * taskptr;"); outtask.println("int numParameters;"); + outtask.println("int numTotal;"); outtask.println("struct parameterdescriptor **descriptorarray;"); outtask.println("char * name;"); outtask.println("};"); @@ -459,6 +469,8 @@ public class BuildCode { output.println("struct taskdescriptor task_"+task.getSafeSymbol()+"={"); output.println("&"+task.getSafeSymbol()+","); output.println("/* number of parameters */" +task.numParameters() + ","); + int numtotal=task.numParameters()+fm.numTags(); + output.println("/* number total parameters */" +numtotal + ","); output.println("parameterdescriptors_"+task.getSafeSymbol()+","); output.println("\""+task.getSymbol()+"\""); output.println("};"); @@ -875,7 +887,7 @@ public class BuildCode { } for(int i=0;imaxtaskparams) @@ -1451,6 +1463,27 @@ public class BuildCode { public void generateFlatFlagActionNode(FlatMethod fm, FlatFlagActionNode ffan, PrintWriter output) { output.println("/* FlatFlagActionNode */"); + + + /* Process tag changes */ + Relation tagsettable=new Relation(); + Relation tagcleartable=new Relation(); + + Iterator tagsit=ffan.getTempTagPairs(); + while (tagsit.hasNext()) { + TempTagPair ttp=(TempTagPair) tagsit.next(); + TempDescriptor objtmp=ttp.getTemp(); + TagDescriptor tag=ttp.getTag(); + TempDescriptor tagtmp=ttp.getTagTemp(); + boolean tagstatus=ffan.getTagChange(ttp); + if (tagstatus) { + tagsettable.put(objtmp, tagtmp); + } else { + tagcleartable.put(objtmp, tagtmp); + } + } + + Hashtable flagandtable=new Hashtable(); Hashtable flagortable=new Hashtable(); @@ -1489,11 +1522,47 @@ public class BuildCode { } } - Iterator orit=flagortable.keySet().iterator(); - while(orit.hasNext()) { - TempDescriptor temp=(TempDescriptor)orit.next(); - int ormask=((Integer)flagortable.get(temp)).intValue(); + + HashSet flagtagset=new HashSet(); + flagtagset.addAll(flagortable.keySet()); + flagtagset.addAll(flagandtable.keySet()); + flagtagset.addAll(tagsettable.keySet()); + flagtagset.addAll(tagcleartable.keySet()); + + Iterator ftit=flagtagset.iterator(); + while(ftit.hasNext()) { + TempDescriptor temp=(TempDescriptor)ftit.next(); + + + Set tagtmps=tagcleartable.get(temp); + if (tagtmps!=null) { + Iterator tagit=tagtmps.iterator(); + while(tagit.hasNext()) { + TempDescriptor tagtmp=(TempDescriptor)tagit.next(); + if (GENERATEPRECISEGC) + output.println("tagclear(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + else + output.println("tagclear((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + } + } + + tagtmps=tagsettable.get(temp); + if (tagtmps!=null) { + Iterator tagit=tagtmps.iterator(); + while(tagit.hasNext()) { + TempDescriptor tagtmp=(TempDescriptor)tagit.next(); + if (GENERATEPRECISEGC) + output.println("tagset(&"+localsprefix+", (struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + else + output.println("tagset((struct ___Object___ *)"+generateTemp(fm, temp)+", "+generateTemp(fm,tagtmp)+");"); + } + } + + int ormask=0; int andmask=0xFFFFFFF; + + if (flagortable.containsKey(temp)) + ormask=((Integer)flagortable.get(temp)).intValue(); if (flagandtable.containsKey(temp)) andmask=((Integer)flagandtable.get(temp)).intValue(); if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) { @@ -1502,56 +1571,5 @@ public class BuildCode { output.println("flagorand("+generateTemp(fm, temp)+", 0x"+Integer.toHexString(ormask)+", 0x"+Integer.toHexString(andmask)+");"); } } - Iterator andit=flagandtable.keySet().iterator(); - while(andit.hasNext()) { - TempDescriptor temp=(TempDescriptor)andit.next(); - int andmask=((Integer)flagandtable.get(temp)).intValue(); - if (!flagortable.containsKey(temp)) { - if (ffan.getTaskType()==FlatFlagActionNode.NEWOBJECT) - output.println("flagorandinit("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");"); - else - output.println("flagorand("+generateTemp(fm, temp)+", 0, 0x"+Integer.toHexString(andmask)+");"); - } - } - - /* Process tag changes */ - Relation tagsettable=new Relation(); - Relation tagcleartable=new Relation(); - - Iterator tagsit=ffan.getTempTagPairs(); - while (tagsit.hasNext()) { - TempTagPair ttp=(TempTagPair) tagsit.next(); - TempDescriptor objtmp=ttp.getTemp(); - TagDescriptor tag=ttp.getTag(); - TempDescriptor tagtmp=ttp.getTagTemp(); - boolean tagstatus=ffan.getTagChange(ttp); - if (tagstatus) { - tagsettable.put(objtmp, tagtmp); - } else { - tagcleartable.put(objtmp, tagtmp); - } - } - - Iterator clearit=tagcleartable.keySet().iterator(); - while(clearit.hasNext()) { - TempDescriptor objtmp=(TempDescriptor)clearit.next(); - Set tagtmps=tagcleartable.get(objtmp); - Iterator tagit=tagtmps.iterator(); - while(tagit.hasNext()) { - TempDescriptor tagtmp=(TempDescriptor)tagit.next(); - output.println("tagclear("+generateTemp(fm, objtmp)+", "+generateTemp(fm,tagtmp)+");"); - } - } - - Iterator setit=tagsettable.keySet().iterator(); - while(setit.hasNext()) { - TempDescriptor objtmp=(TempDescriptor)setit.next(); - Set tagtmps=tagcleartable.get(objtmp); - Iterator tagit=tagtmps.iterator(); - while(tagit.hasNext()) { - TempDescriptor tagtmp=(TempDescriptor)tagit.next(); - output.println("tagset("+generateTemp(fm, objtmp)+", "+generateTemp(fm,tagtmp)+");"); - } - } } } diff --git a/Robust/src/IR/Tree/BuildIR.java b/Robust/src/IR/Tree/BuildIR.java index bfcf62a7..d82d0350 100644 --- a/Robust/src/IR/Tree/BuildIR.java +++ b/Robust/src/IR/Tree/BuildIR.java @@ -209,7 +209,8 @@ public class BuildIR { NameDescriptor nd=parseName(snn); cn.setSuper(nd.toString()); } else { - if (!cn.getSymbol().equals(TypeUtil.ObjectClass)) + if (!(cn.getSymbol().equals(TypeUtil.ObjectClass)|| + cn.getSymbol().equals(TypeUtil.TagClass))) cn.setSuper(TypeUtil.ObjectClass); } cn.setModifiers(parseModifiersList(pn.getChild("modifiers"))); diff --git a/Robust/src/IR/TypeUtil.java b/Robust/src/IR/TypeUtil.java index 9e09427e..7c67d49e 100644 --- a/Robust/src/IR/TypeUtil.java +++ b/Robust/src/IR/TypeUtil.java @@ -5,6 +5,7 @@ public class TypeUtil { public static final String StringClass="String"; public static final String ObjectClass="Object"; public static final String StartupClass="StartupObject"; + public static final String TagClass="TagDescriptor"; State state; Hashtable supertable; Hashtable subclasstable; diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index b0ee390d..16ae7181 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -80,7 +80,7 @@ public class Main { readSourceFile(state, ClassLibraryPrefix+"ObjectJava.java"); } else { readSourceFile(state, ClassLibraryPrefix+"Object.java"); - // readSourceFile(state, ClassLibraryPrefix+"TagDescriptor.java"); + readSourceFile(state, ClassLibraryPrefix+"TagDescriptor.java"); } if (state.TASK) { diff --git a/Robust/src/README b/Robust/src/README index 8b709157..55b17231 100644 --- a/Robust/src/README +++ b/Robust/src/README @@ -1,54 +1 @@ -I. Compiling a simple test program - -1) Go to the Robust directory and type "cvs update" - -2) Go into the src directory and build the compiler by typing: -make clean -make - -3) To run the compiler on a source file (For example to compile -Tests/Array.java): -java -cp ../cup/:. Main.Main -mainclass Array Tests/Array.java -NOTE: The mainclass option specifies the class that contains the main method - -4) To compiler and link the output of the compiler do: -gcc -IRuntime -I. -O0 -g methods.c Runtime/runtime.c - -5) To run the binary type: -./a.out - - - -II. Command line options - -To see all the legal command line options for the compiler type: -java -cp ../cup:. Main.Main -help - - - -III. Using Garbage Collection -(DEPRECATED...THIS IS FOR CONSERVATIVE GC ONLY...WE NOW HAVE PRECISE GC.) - - -1) Download the Hans Boehm garbage collector - -2) Make a directory called gc in the Runtime directory & untar the gc into this directory - -3) ./configure --prefix={RUNTIME DIRECTORY}; make;make install to build -(Modify the prefix to the appropriate path for the runtime directory. - -4) Make sure the gc libraries are placed in Runtime/lib and the include files in Runtime/include - -5) Change step 4 in the build procedure to: -gcc -IRuntime -I. -IRuntime/include -DBOEHM_GC -LRuntime/lib/ -lgc -O9 -g methods.c Runtime/runtime.c - -IV. High level organization of the compiler: -1. Lexer is in src/Lex -2. Parser is built from the grammar in Parse/java14.cup -3. Internal Representations are in the the IR subdirectory -3a. Tree representation is in IR/Tree (constructed by IR/Tree/BuildTree) -3b. Flattened representation in is IR/Flat (constructed by IR/Flat/BuildFlat) -4. Code is generated from the flattened representation by IR/Flat/BuildCode -5. Main/Main.java is the top level -6. ClassLibrary contains the class library -7. Runtime contains the runtime \ No newline at end of file +See the wiki page at http://demsky.eecs.uci.edu/compiler/ \ No newline at end of file diff --git a/Robust/src/Runtime/GenericHashtable.c b/Robust/src/Runtime/GenericHashtable.c index 2742cc26..ac50f964 100755 --- a/Robust/src/Runtime/GenericHashtable.c +++ b/Robust/src/Runtime/GenericHashtable.c @@ -11,6 +11,10 @@ #include "dmalloc.h" #endif +void * getfirstkey(struct genhashtable *ht) { + return ht->list->src; +} + int genputtable(struct genhashtable *ht, void * key, void * object) { unsigned int bin=genhashfunction(ht,key); struct genpointerlist * newptrlist=(struct genpointerlist *) RUNMALLOC(sizeof(struct genpointerlist)); diff --git a/Robust/src/Runtime/GenericHashtable.h b/Robust/src/Runtime/GenericHashtable.h index 3a65a4c4..951f044c 100755 --- a/Robust/src/Runtime/GenericHashtable.h +++ b/Robust/src/Runtime/GenericHashtable.h @@ -32,6 +32,7 @@ struct geniterator { }; struct genhashtable * genallocatehashtable(unsigned int (*hash_function)(void *),int (*comp_function)(void *,void *)); +void * getfirstkey(struct genhashtable *ht); void genfreehashtable(struct genhashtable * ht); void genrehash(struct genhashtable * ht); void * getnext(struct genhashtable *,void *); diff --git a/Robust/src/Runtime/Queue.c b/Robust/src/Runtime/Queue.c index a29e96b0..5a8da1fa 100644 --- a/Robust/src/Runtime/Queue.c +++ b/Robust/src/Runtime/Queue.c @@ -8,6 +8,10 @@ struct Queue * createQueue() { return RUNMALLOC(sizeof(struct Queue)); } +void freeQueue(struct Queue * q) { + RUNFREE(q); +} + int isEmpty(struct Queue *queue) { return queue->head==NULL; } @@ -27,6 +31,16 @@ struct QueueItem * addNewItem(struct Queue * queue, void * ptr) { return item; } +struct QueueItem * findItem(struct Queue * queue, void *ptr) { + struct QueueItem * item=queue->head; + while(item!=NULL) { + if (item->objectptr==ptr) + return item; + item=item->next; + } + return NULL; +} + void removeItem(struct Queue * queue, struct QueueItem * item) { struct QueueItem * prev=item->prev; struct QueueItem * next=item->next; diff --git a/Robust/src/Runtime/Queue.h b/Robust/src/Runtime/Queue.h index 6e9f63dc..ef25820d 100644 --- a/Robust/src/Runtime/Queue.h +++ b/Robust/src/Runtime/Queue.h @@ -13,8 +13,10 @@ struct QueueItem { struct QueueItem * prev; }; +void freeQueue(struct Queue * q); struct Queue * createQueue(); struct QueueItem * addNewItem(struct Queue * queue, void * ptr); +struct QueueItem * findItem(struct Queue * queue, void * ptr); void removeItem(struct Queue * queue, struct QueueItem * item); int isEmpty(struct Queue *queue); struct QueueItem * getTail(struct Queue * queue); diff --git a/Robust/src/Runtime/SimpleHash.h b/Robust/src/Runtime/SimpleHash.h index 3d89d6e2..2a25d6cc 100755 --- a/Robust/src/Runtime/SimpleHash.h +++ b/Robust/src/Runtime/SimpleHash.h @@ -60,7 +60,7 @@ struct RuntimeNode { }; struct RuntimeIterator { - struct RuntimeNode *cur, *tail; + struct RuntimeNode *cur; }; inline struct RuntimeIterator * noargallocateRuntimeIterator(); diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index 69f32a6a..8dc7d5fe 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -21,7 +21,7 @@ #define HEAPSIZE(x,y) (((int)((x)/0.6))+y) #ifdef TASK -extern struct Queue * activetasks; +extern struct genhashtable * activetasks; extern struct parameterwrapper * objectqueues[NUMCLASSES]; extern struct genhashtable * failedtasks; extern struct taskparamdescriptor *currtpd; @@ -208,22 +208,24 @@ void collect(struct garbagelist * stackptr) { } - { /* Update active tasks */ - struct QueueItem * ptr=activetasks->head; - while (ptr!=NULL) { - struct taskparamdescriptor *tpd=ptr->objectptr; + { + struct genpointerlist * ptr=activetasks->list; + while(ptr!=NULL) { + struct taskparamdescriptor *tpd=ptr->src; int i; for(i=0;inumParameters;i++) { - void *orig=tpd->parameterArray[i]; - void *copy; + void * orig=tpd->parameterArray[i]; + void * copy; if (gc_createcopy(orig, ©)) enqueue(orig); tpd->parameterArray[i]=copy; } - ptr=ptr->next; + ptr=ptr->inext; } + genrehash(activetasks); } + /* Update failed tasks */ { struct genpointerlist * ptr=failedtasks->list; diff --git a/Robust/src/Runtime/runtime.c b/Robust/src/Runtime/runtime.c index b905affb..0c5b4c5c 100644 --- a/Robust/src/Runtime/runtime.c +++ b/Robust/src/Runtime/runtime.c @@ -11,6 +11,12 @@ #include #include "option.h" +#define ARRAYSET(array, type, index, value) \ +((type *)(&(& array->___length___)[1]))[index]=value + +#define ARRAYGET(array, type, index) \ +((type *)(&(& array->___length___)[1]))[index] + extern int classsize[]; jmp_buf error_handler; int instructioncount; @@ -40,7 +46,7 @@ int instaccum=0; #include "instrument.h" #endif -struct Queue * activetasks; +struct genhashtable * activetasks; struct parameterwrapper * objectqueues[NUMCLASSES]; struct genhashtable * failedtasks; struct taskparamdescriptor * currtpd; @@ -61,8 +67,10 @@ int main(int argc, char **argv) { failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd, (int (*)(void *,void *)) &comparetpd); /* Create queue of active tasks */ - activetasks=createQueue(); - + activetasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd, + (int (*)(void *,void *)) &comparetpd); + + /* Process task information */ processtasks(); @@ -119,10 +127,207 @@ int comparetpd(struct taskparamdescriptor *ftd1, struct taskparamdescriptor *ftd return 1; } +#define TAGARRAYINTERVAL 10 +#define OBJECTARRAYINTERVAL 10 + +/* This function sets a tag. */ +#ifdef PRECISE_GC +void tagset(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) { +#else +void tagset(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) { +#endif + struct ___Object___ * tagptr=obj->___tags___; + if (tagptr==NULL) { + obj->___tags___=(struct ___Object___ *)tagd; + } else { + /* Have to check if it is already set */ + if (tagptr->type==TAGTYPE) { + struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr; + if (td==tagd) + return; +#ifdef PRECISE_GC + int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd}; + struct ArrayObject * ao=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL); + obj=(struct ___Object___ *)ptrarray[2]; + tagd=(struct ___TagDescriptor___ *)ptrarray[3]; + td=(struct ___TagDescriptor___ *) obj->___tags___; +#else + struct ArrayObject * ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL); +#endif + ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td); + ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd); + obj->___tags___=(struct ___Object___ *) ao; + ao->___cachedCode___=2; + } else { + /* Array Case */ + int i; + struct ArrayObject *ao=(struct ArrayObject *) tagptr; + for(i=0;i___cachedCode___;i++) { + struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___*, i); + if (td==tagd) + return; + } + if (ao->___cachedCode______length___) { + ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd); + ao->___cachedCode___++; + } else { +#ifdef PRECISE_GC + int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd}; + struct ArrayObject * aonew=allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___); + obj=(struct ___Object___ *)ptrarray[2]; + tagd=(struct ___TagDescriptor___ *) ptrarray[3]; + ao=(struct ArrayObject *)obj->___tags___; +#else + struct ArrayObject * aonew=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___); +#endif + aonew->___cachedCode___=ao->___length___+1; + for(i=0;i___length___;i++) { + ARRAYSET(aonew, struct ___TagDescriptor___*, i, ARRAYGET(ao, struct ___TagDescriptor___*, i)); + } + ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd); + } + } + } + + { + struct ___Object___ * tagset=tagd->___tagset___; + + if(tagset==NULL) { + tagd->___tagset___=obj; + } else if (tagset->type!=OBJECTARRAYTYPE) { +#ifdef PRECISE_GC + int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd}; + struct ArrayObject * ao=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL); + obj=(struct ___Object___ *)ptrarray[2]; + tagd=(struct ___TagDescriptor___ *)ptrarray[3]; +#else + struct ArrayObject * ao=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL); +#endif + ARRAYSET(ao, struct ___Object___ *, 0, tagd->___tagset___); + ARRAYSET(ao, struct ___Object___ *, 1, obj); + ao->___cachedCode___=2; + tagd->___tagset___=(struct ___Object___ *)ao; + } else { + struct ArrayObject *ao=(struct ArrayObject *) tagset; + if (ao->___cachedCode______length___) { + ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj); + } else { + int i; +#ifdef PRECISE_GC + int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd}; + struct ArrayObject * aonew=allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___); + obj=(struct ___Object___ *)ptrarray[2]; + tagd=(struct ___TagDescriptor___ *)ptrarray[3]; + ao=(struct ArrayObject *)tagd->___tagset___; +#else + struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL); +#endif + aonew->___cachedCode___=ao->___cachedCode___+1; + for(i=0;i___length___;i++) { + ARRAYSET(aonew, struct ___Object___*, i, ARRAYGET(ao, struct ___Object___*, i)); + } + ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj); + tagd->___tagset___=(struct ___Object___ *) ao; + } + } + } +} + +/* This function clears a tag. */ +#ifdef PRECISE_GC +void tagclear(void *ptr, struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) { +#else +void tagclear(struct ___Object___ * obj, struct ___TagDescriptor___ * tagd) { +#endif + /* We'll assume that tag is alway there. + Need to statically check for this of course. */ + struct ___Object___ * tagptr=obj->___tags___; + + if (tagptr->type==TAGTYPE) { + if ((struct ___TagDescriptor___ *)tagptr==tagd) + obj->___tags___=NULL; + else + printf("ERROR 1 in tagclear\n"); + } else { + struct ArrayObject *ao=(struct ArrayObject *) tagptr; + int i; + for(i=0;i___cachedCode___;i++) { + struct ___TagDescriptor___ * td=ARRAYGET(ao, struct ___TagDescriptor___ *, i); + if (td==tagd) { + ao->___cachedCode___--; + if (i___cachedCode___) + ARRAYSET(ao, struct ___TagDescriptor___ *, i, ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___)); + ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL); + if (ao->___cachedCode___==0) + obj->___tags___=NULL; + goto PROCESSCLEAR; + } + } + printf("ERROR 2 in tagclear\n"); + } + PROCESSCLEAR: + { + struct ___Object___ *tagset=tagd->___tagset___; + if (tagset->type!=OBJECTARRAYTYPE) { + if (tagset==obj) + tagd->___tagset___=NULL; + else + printf("ERROR 3 in tagclear\n"); + } else { + struct ArrayObject *ao=(struct ArrayObject *) tagset; + int i; + for(i=0;i___cachedCode___;i++) { + struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i); + if (tobj==obj) { + ao->___cachedCode___--; + if (i___cachedCode___) + ARRAYSET(ao, struct ___Object___ *, i, ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___)); + ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL); + if (ao->___cachedCode___==0) + tagd->___tagset___=NULL; + goto ENDCLEAR; + } + } + printf("ERROR 4 in tagclear\n"); + } + } + ENDCLEAR: + return; + +} + +/* This function allocates a new tag. */ +#ifdef PRECISE_GC +struct ___TagDescriptor___ * allocate_tag(void *ptr, int index) { + struct ___TagDescriptor___ * v=(struct ___TagDescriptor___ *) mygcmalloc((struct garbagelist *) ptr, classsize[STARTUPTYPE]); +#else +struct ___TagDescriptor___ * allocate_tag(int index) { + struct ___TagDescriptor___ * v=FREEMALLOC(classsize[STARTUPTYPE]); +#endif + v->type=STARTUPTYPE; + v->flag=index; + return v; +} + + + /* This function updates the flag for object ptr. It or's the flag with the or mask and and's it with the andmask. */ +void flagbody(struct ___Object___ *ptr, int flag); + void flagorand(void * ptr, int ormask, int andmask) { + int oldflag=((int *)ptr)[1]; + int flag=ormask|oldflag; + flag&=andmask; + // Not sure why this was necessary + // if (flag==oldflag) /* Don't do anything */ + // return; + //else + flagbody(ptr, flag); +} + +void intflagorand(void * ptr, int ormask, int andmask) { int oldflag=((int *)ptr)[1]; int flag=ormask|oldflag; flag&=andmask; @@ -138,100 +343,149 @@ void flagorandinit(void * ptr, int ormask, int andmask) { flagbody(ptr,flag); } -void flagbody(void *ptr, int flag) { - struct RuntimeHash *flagptr=(struct RuntimeHash *)(((int*)ptr)[2]); - ((int*)ptr)[1]=flag; - +void flagbody(struct ___Object___ *ptr, int flag) { + struct parameterwrapper *flagptr=(struct parameterwrapper *)ptr->flagptr; + ptr->flag=flag; + /*Remove object from all queues */ while(flagptr!=NULL) { - struct RuntimeHash *next; - RuntimeHashget(flagptr, (int) ptr, (int *) &next); - RuntimeHashremove(flagptr, (int)ptr, (int) next); + struct parameterwrapper *next; + struct ___Object___ * tag=ptr->___tags___; + RuntimeHashget(flagptr->objectset, (int) ptr, (int *) &next); + RuntimeHashremove(flagptr->objectset, (int)ptr, (int) next); flagptr=next; } { struct QueueItem *tmpptr; - struct parameterwrapper * parameter=objectqueues[((int *)ptr)[0]]; + struct parameterwrapper * parameter=objectqueues[ptr->type]; int i; - struct RuntimeHash * prevptr=NULL; + struct parameterwrapper * prevptr=NULL; + struct ___Object___ *tagptr=ptr->___tags___; + + /* Outer loop iterates through all parameter queues an object of + this type could be in. */ + while(parameter!=NULL) { + /* Check tags */ + if (parameter->numbertags>0) { + if (tagptr==NULL) + goto nextloop; + else if(tagptr->type==TAGTYPE) { + struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr; + for(i=0;inumbertags;i++) { + //slotid is parameter->tagarray[2*i]; + int tagid=parameter->tagarray[2*i+1]; + if (tagid!=tagptr->flag) + goto nextloop; /*We don't have this tag */ + } + } else { + struct ArrayObject * ao=(struct ArrayObject *) tagptr; + for(i=0;inumbertags;i++) { + //slotid is parameter->tagarray[2*i]; + int tagid=parameter->tagarray[2*i+1]; + int j; + for(j=0;j___cachedCode___;j++) { + if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, i)->flag) + goto foundtag; + } + goto nextloop; + foundtag: + ; + } + } + } + + /* Check flags */ for(i=0;inumberofterms;i++) { int andmask=parameter->intarray[i*2]; int checkmask=parameter->intarray[i*2+1]; if ((flag&andmask)==checkmask) { - RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr); - prevptr=parameter->objectset; - { - struct RuntimeIterator iteratorarray[MAXTASKPARAMS]; - void * taskpointerarray[MAXTASKPARAMS]; - int j; - int numparams=parameter->task->numParameters; - int done=1; - struct taskdescriptor * task=parameter->task; - int newindex=-1; - for(j=0;jdescriptorarray[j]->queue; - if (parameter==pw) { - taskpointerarray[j]=ptr; - newindex=j; - } else { - RuntimeHashiterator(pw->objectset, &iteratorarray[j]); - if (RunhasNext(&iteratorarray[j])) { - taskpointerarray[j]=(void *) Runkey(&iteratorarray[j]); - Runnext(&iteratorarray[j]); - } else { - done=0; - break; /* No tasks to dispatch */ - } - } - } - /* Queue task items... */ - - while(done) { - struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor)); - tpd->task=task; - tpd->numParameters=numparams; - tpd->parameterArray=RUNMALLOC(sizeof(void *)*numparams); - for(j=0;jparameterArray[j]=taskpointerarray[j]; - /* Queue task */ - if (!gencontains(failedtasks, tpd)) - addNewItem(activetasks, tpd); - else { - RUNFREE(tpd->parameterArray); - RUNFREE(tpd); - } - - /* This loop iterates to the next parameter combination */ - for(j=0;jdescriptorarray[j]->queue, &iteratorarray[j]); - } else { - done=0; - break; - } - } - } - } + enqueuetasks(parameter, prevptr, ptr); + prevptr=parameter; break; } } + nextloop: parameter=parameter->next; } - ((struct RuntimeHash **)ptr)[2]=prevptr; + ptr->flagptr=prevptr; } } + +void enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr) { + void * taskpointerarray[MAXTASKPARAMS]; + int j; + int numparams=parameter->task->numParameters; + int numiterators=parameter->task->numTotal-1; + + struct taskdescriptor * task=parameter->task; + + RuntimeHashadd(parameter->objectset, (int) ptr, (int) prevptr); + + /* Add enqueued object to parameter vector */ + taskpointerarray[parameter->slot]=ptr; + /* Reset iterators */ + for(j=0;jiterators[j]); + } + + /* Find initial state */ + for(j=0;jiterators[j], taskpointerarray)) + toiNext(¶meter->iterators[j], taskpointerarray); + else if (j>0) { + /* Need to backtrack */ + toiReset(¶meter->iterators[j]); + j--; + goto backtrackinit; + } else { + /* Nothing to enqueue */ + return; + } + } + + + while(1) { + /* Enqueue current state */ + struct taskparamdescriptor *tpd=RUNMALLOC(sizeof(struct taskparamdescriptor)); + tpd->task=task; + tpd->numParameters=numiterators+1; + tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1)); + for(j=0;j<=numiterators;j++) + tpd->parameterArray[j]=taskpointerarray[j]; + + /* Enqueue task */ + if (!gencontains(failedtasks, tpd)&&!gencontains(activetasks,tpd)) { + genputtable(activetasks, tpd, tpd); + } else { + RUNFREE(tpd->parameterArray); + RUNFREE(tpd); + } + + /* This loop iterates to the next parameter combination */ + if (numiterators==0) + return; + + for(j=numiterators-1; jiterators[j], taskpointerarray)) + toiNext(¶meter->iterators[j], taskpointerarray); + else if (j>0) { + /* Need to backtrack */ + toiReset(¶meter->iterators[j]); + j--; + goto backtrackinc; + } else { + /* Nothing more to enqueue */ + return; + } + } + } +} + /* Handler for signals. The signals catch null pointer errors and arithmatic errors. */ @@ -292,7 +546,7 @@ void executetasks() { mmap(0, 0x1000, 0, MAP_SHARED|MAP_FIXED|MAP_ANON, -1, 0); newtask: - while(!isEmpty(activetasks)||(maxreadfd>0)) { + while((hashsize(activetasks)>0)||(maxreadfd>0)) { /* Check if any filedescriptors have IO pending */ if (maxreadfd>0) { @@ -311,7 +565,7 @@ void executetasks() { void * objptr; // printf("Setting fd %d\n",fd); if (RuntimeHashget(fdtoobject, fd,(int *) &objptr)) { - flagorand(objptr,1,0xFFFFFFFF); /* Set the first flag to 1 */ + intflagorand(objptr,1,0xFFFFFFFF); /* Set the first flag to 1 */ } } } @@ -319,11 +573,10 @@ void executetasks() { } /* See if there are any active tasks */ - if (!isEmpty(activetasks)) { + if (hashsize(activetasks)>0) { int i; - struct QueueItem * qi=(struct QueueItem *) getTail(activetasks); - currtpd=(struct taskparamdescriptor *) qi->objectptr; - removeItem(activetasks, qi); + currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks); + genfreekey(activetasks, currtpd); /* Check if this task has failed */ if (gencontains(failedtasks, currtpd)) { @@ -332,19 +585,39 @@ void executetasks() { RUNFREE(currtpd); goto newtask; } - + int numparams=currtpd->task->numParameters; + int numtotal=currtpd->task->numTotal; + /* Make sure that the parameters are still in the queues */ - for(i=0;itask->numParameters;i++) { + for(i=0;iparameterArray[i]; struct parameterdescriptor * pd=currtpd->task->descriptorarray[i]; struct parameterwrapper *pw=(struct parameterwrapper *) pd->queue; + int j; + /* Check that object is still in queue */ if (!RuntimeHashcontainskey(pw->objectset, (int) parameter)) { RUNFREE(currtpd->parameterArray); RUNFREE(currtpd); goto newtask; } + /* Check that object still has necessary tags */ + for(j=0;jnumbertags;j++) { + int slotid=pd->tagarray[2*i]+numparams; + struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid]; + if (!containstag(parameter, tagd)) { + RUNFREE(currtpd->parameterArray); + RUNFREE(currtpd); + goto newtask; + } + } + taskpointerarray[i+OFFSET]=parameter; } + /* Copy the tags */ + for(;iparameterArray[i]; + } + { /* Checkpoint the state */ forward=allocateRuntimeHash(100); @@ -397,6 +670,100 @@ void executetasks() { } } +/* This function processes an objects tags */ +void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams) { + int i; + + for(i=0;inumbertags;i++) { + int slotid=pd->tagarray[2*i]; + int tagid=pd->tagarray[2*i+1]; + + if (statusarray[slotid+numparams]==0) { + parameter->iterators[*iteratorcount].istag=1; + parameter->iterators[*iteratorcount].tagid=tagid; + parameter->iterators[*iteratorcount].slot=slotid+numparams; + parameter->iterators[*iteratorcount].tagobjectslot=index; + statusarray[slotid+numparams]=1; + (*iteratorcount)++; + } + } +} + + +void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams) { + int i; + int tagcount=0; + struct RuntimeHash * objectset=((struct parameterwrapper *)pd->queue)->objectset; + + parameter->iterators[*iteratorcount].istag=0; + parameter->iterators[*iteratorcount].slot=index; + parameter->iterators[*iteratorcount].objectset=objectset; + statusarray[index]=1; + + for(i=0;inumbertags;i++) { + int slotid=pd->tagarray[2*i]; + int tagid=pd->tagarray[2*i+1]; + if (statusarray[slotid+numparams]!=0) { + /* This tag has already been enqueued, use it to narrow search */ + parameter->iterators[*iteratorcount].tagbindings[tagcount]=slotid+numparams; + tagcount++; + } + } + parameter->iterators[*iteratorcount].numtags=tagcount; + + (*iteratorcount)++; +} + +/* This function builds the iterators for a task & parameter */ + +void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter) { + int statusarray[MAXTASKPARAMS]; + int i; + int numparams=task->numParameters; + int iteratorcount=0; + for(i=0;idescriptorarray[index], index, parameter, & iteratorcount, statusarray, numparams); + + while(1) { + loopstart: + /* Check for objects with existing tags */ + for(i=0;idescriptorarray[i]; + int j; + for(j=0;jnumbertags;j++) { + int slotid=pd->tagarray[2*j]; + if(statusarray[slotid+numparams]!=0) { + processobject(parameter, i, pd, &iteratorcount, statusarray, numparams); + processtags(pd, i, parameter, &iteratorcount, statusarray, numparams); + goto loopstart; + } + } + } + } + /* Nothing with a tag enqueued */ + + for(i=0;idescriptorarray[i]; + processobject(parameter, i, pd, &iteratorcount, statusarray, numparams); + processtags(pd, i, parameter, &iteratorcount, statusarray, numparams); + goto loopstart; + } + } + + /* Nothing left */ + return; + } +} + + + + /* This function processes the task information to create queues for each parameter type. */ @@ -415,15 +782,147 @@ void processtasks() { parameter->objectset=allocateRuntimeHash(10); parameter->numberofterms=param->numberterms; parameter->intarray=param->intarray; + parameter->numbertags=param->numbertags; + parameter->tagarray=param->tagarray; parameter->task=task; /* Link new queue in */ while((*ptr)!=NULL) ptr=&((*ptr)->next); (*ptr)=parameter; } + + /* Build iterators for parameters */ + for(j=0;jnumParameters;j++) { + struct parameterdescriptor *param=task->descriptorarray[j]; + struct parameterwrapper *parameter=param->queue; + parameter->slot=j; + builditerators(task, j, parameter); + } + } +} + +void toiReset(struct tagobjectiterator * it) { + if (it->istag) { + it->tagobjindex=0; + } else if (it->numtags>0) { + it->tagobjindex=0; + } else { + RuntimeHashiterator(it->objectset, &it->it); + } +} + +int toiHasNext(struct tagobjectiterator *it, void ** objectarray) { + if (it->istag) { + /* Iterate tag */ + /* Get object with tags */ + struct ___Object___ *obj=objectarray[it->tagobjectslot]; + struct ___Object___ *tagptr=obj->___tags___; + if (tagptr->type==TAGTYPE) { + if ((it->tagobjindex==0)&& /* First object */ + (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */ + return 1; + else + return 0; + } else { + struct ArrayObject *ao=(struct ArrayObject *) tagptr; + int tagindex=it->tagobjindex; + for(;tagindex___cachedCode___;tagindex++) { + struct ___TagDescriptor___ *td=ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex); + if (td->flag==it->tagid) { + it->tagobjindex=tagindex; /* Found right type of tag */ + return 1; + } + } + return 0; + } + } else if (it->numtags>0) { + /* Use tags to locate appropriate objects */ + struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]]; + struct ___Object___ *objptr=tag->___tagset___; + int i; + if (objptr->type!=OBJECTARRAYTYPE) { + if (it->tagobjindex>0) + return 0; + if (!RuntimeHashcontainskey(it->objectset, (int) objptr)) + return 0; + for(i=1;inumtags;i++) { + struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]]; + if (!containstag(objptr,tag2)) + return 0; + } + return 1; + } else { + struct ArrayObject *ao=(struct ArrayObject *) objptr; + int tagindex; + int i; + for(tagindex=it->tagobjindex;tagindex___cachedCode___;tagindex++) { + struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex); + if (!RuntimeHashcontainskey(it->objectset, (int) objptr)) + continue; + for(i=1;inumtags;i++) { + struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]]; + if (!containstag(objptr,tag2)) + goto nexttag; + } + return 1; + nexttag: + ; + } + it->tagobjindex=tagindex; + return 0; + } + } else { + return RunhasNext(&it->it); } } +int containstag(struct ___Object___ *ptr, struct ___TagDescriptor___ *tag) { + int j; + struct ___Object___ * objptr=tag->___tagset___; + if (objptr->type==OBJECTARRAYTYPE) { + struct ArrayObject *ao=(struct ArrayObject *)objptr; + for(j=0;j___cachedCode___;j++) { + if (ptr==ARRAYGET(ao, struct ___Object___*, j)) + return 1; + } + return 0; + } else + return objptr==ptr; +} + +void toiNext(struct tagobjectiterator *it , void ** objectarray) { + /* hasNext has all of the intelligence */ + if(it->istag) { + /* Iterate tag */ + /* Get object with tags */ + struct ___Object___ *obj=objectarray[it->tagobjectslot]; + struct ___Object___ *tagptr=obj->___tags___; + if (tagptr->type==TAGTYPE) { + it->tagobjindex++; + objectarray[it->slot]=tagptr; + } else { + struct ArrayObject *ao=(struct ArrayObject *) tagptr; + objectarray[it->slot]=ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++); + } + } else if (it->numtags>0) { + /* Use tags to locate appropriate objects */ + struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]]; + struct ___Object___ *objptr=tag->___tagset___; + if (objptr->type!=OBJECTARRAYTYPE) { + it->tagobjindex++; + objectarray[it->slot]=objptr; + } else { + struct ArrayObject *ao=(struct ArrayObject *) objptr; + objectarray[it->slot]=ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++); + } + } else { + /* Iterate object */ + objectarray[it->slot]=(void *)Runkey(&it->it); + Runnext(&it->it); + } +} + + #endif void exithandler(int sig, siginfo_t *info, void * uap) { diff --git a/Robust/src/Runtime/runtime.h b/Robust/src/Runtime/runtime.h index 60b656aa..844039e6 100644 --- a/Robust/src/Runtime/runtime.h +++ b/Robust/src/Runtime/runtime.h @@ -46,18 +46,37 @@ void createstartupobject(); #ifdef TASK #include "SimpleHash.h" #include "task.h" +#include "structdefs.h" + void flagorand(void * ptr, int ormask, int andmask); void flagorandinit(void * ptr, int ormask, int andmask); -void flagbody(void *ptr, int flag); void executetasks(); void processtasks(); +struct tagobjectiterator { + int istag; /* 0 if object iterator, 1 if tag iterator */ + struct RuntimeIterator it; /* Object iterator */ + struct RuntimeHash * objectset; + int slot; + int tagobjindex; /* Index for tag or object depending on use */ + /*if tag we have an object binding */ + int tagid; + int tagobjectslot; + /*if object, we may have one or more tag bindings */ + int numtags; + int tagbindings[MAXTASKPARAMS-1]; /* list slots */ +}; + struct parameterwrapper { struct parameterwrapper *next; struct RuntimeHash * objectset; int numberofterms; int * intarray; + int numbertags; + int * tagarray; struct taskdescriptor * task; + int slot; + struct tagobjectiterator iterators[MAXTASKPARAMS-1]; }; struct taskparamdescriptor { @@ -66,13 +85,17 @@ struct taskparamdescriptor { void ** parameterArray; }; -struct tpdlist { - struct taskparamdescriptor * task; - struct tpdlist * next; -}; - int hashCodetpd(struct taskparamdescriptor *); int comparetpd(struct taskparamdescriptor *, struct taskparamdescriptor *); + +void toiReset(struct tagobjectiterator * it); +int toiHasNext(struct tagobjectiterator *it, void ** objectarray); +void toiNext(struct tagobjectiterator *it , void ** objectarray); +void processobject(struct parameterwrapper *parameter, int index, struct parameterdescriptor *pd, int *iteratorcount, int * statusarray, int numparams); +void processtags(struct parameterdescriptor *pd, int index, struct parameterwrapper *parameter, int * iteratorcount, int *statusarray, int numparams); +void builditerators(struct taskdescriptor * task, int index, struct parameterwrapper * parameter); +void enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr); + #endif #endif