bug fixes in multicore gc
authorjzhou <jzhou>
Wed, 26 Aug 2009 00:10:57 +0000 (00:10 +0000)
committerjzhou <jzhou>
Wed, 26 Aug 2009 00:10:57 +0000 (00:10 +0000)
Robust/src/Runtime/mem.c
Robust/src/Runtime/multicoregarbage.c
Robust/src/Runtime/multicoreruntime.h
Robust/src/Runtime/multicoretask.c

index 0324f170d2d0535adc5bea7e5e5f881848be1a27..baedcefcac51d9d82715d081cac0d062c92d35a4 100644 (file)
@@ -23,6 +23,7 @@ void * mycalloc_share(struct garbagelist * stackptr,
                                                                                        int size) {
        void * p = NULL;
   int isize = 2*BAMBOO_CACHE_LINE_SIZE-4+(size-1)&(~BAMBOO_CACHE_LINE_MASK);
+       bool hasgc = false;
 memalloc:
   BAMBOO_START_CRITICAL_SECTION_MEM();
   p = BAMBOO_SHARE_MEM_CALLOC_I(m, isize); // calloc(m, isize);
@@ -32,8 +33,14 @@ memalloc:
   if(p == NULL) {
                // no more global shared memory
                BAMBOO_CLOSE_CRITICAL_SECTION_MEM();
-               // start gc
-               gc(stackptr);
+               if(!hasgc) {
+                       // start gc
+                       gc(stackptr);
+                       hasgc = true;
+               } else {
+                       // no more global shared memory
+                       BAMBOO_EXIT(0xc002);
+               }
 
                // try to malloc again
                goto memalloc;
@@ -54,7 +61,7 @@ void * mycalloc_share(int m,
   p = BAMBOO_SHARE_MEM_CALLOC_I(m, isize); // calloc(m, isize);
   if(p == NULL) {
                // no more global shared memory
-               BAMBOO_EXIT(0xc002);
+               BAMBOO_EXIT(0xc003);
   }
   BAMBOO_CLOSE_CRITICAL_SECTION_MEM();
   return 
@@ -68,7 +75,7 @@ void * mycalloc_i(int m,
   int isize = size; 
   p = BAMBOO_LOCAL_MEM_CALLOC(m, isize); // calloc(m, isize);
   if(p == NULL) {
-         BAMBOO_EXIT(0xc003);
+         BAMBOO_EXIT(0xc004);
   }
   return p;
 }
index 3cd45fea62127fb46ea2b8e8271624e4e4d864c7..894ef49fdc4619311766c20aea6253cb6b521c87 100644 (file)
@@ -61,6 +61,10 @@ inline void dumpSMem() {
 #endif
 
 inline void gc_enqueue(void *ptr) {
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe601);
+       BAMBOO_DEBUGPRINT_REG(ptr);
+#endif
   if (gcheadindex==NUMPTRS) {
     struct pointerblock * tmp;
     if (gcspare!=NULL) {
@@ -117,6 +121,9 @@ inline int gc_moreItems2() {
 inline void gc_lobjenqueue(void *ptr, 
                                       int length, 
                                                                                       int host) {
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe901);
+#endif
   if (gclobjheadindex==NUMLOBJPTRS) {
     struct lobjpointerblock * tmp;
     if (gclobjspare!=NULL) {
@@ -131,12 +138,12 @@ inline void gc_lobjenqueue(void *ptr,
   } // if (gclobjheadindex==NUMLOBJPTRS)
   gclobjhead->lobjs[gclobjheadindex]=ptr;
        gclobjhead->lengths[gclobjheadindex]=length;
-       gclobjhead->hosts[gclobjheadindex]=host;
-       /*if(oirg == NULL) {
-               gclobjhead->origs[gclobjheadindex++]=ptr;
-       } else {
-               gclobjhead->origs[gclobjheadindex++]=orig;
-       }*/
+       gclobjhead->hosts[gclobjheadindex++]=host;
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
+       BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
+       BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
+#endif
 } // void gc_lobjenqueue(void *ptr...)
 
 // dequeue and destroy the queue
@@ -204,13 +211,42 @@ inline void gettype_size(void * ptr,
        *tsize = size;
 }
 
-// bug here TODO
 inline bool isLarge(void * ptr, 
                                int * ttype, 
                                                                                int * tsize) {
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe701);
+               BAMBOO_DEBUGPRINT_REG(ptr);
+#endif
        // check if a pointer is referring to a large object
        gettype_size(ptr, ttype, tsize);
-       return(!isLocal(ptr + *tsize));
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(*tsize);
+#endif
+       int bound = (BAMBOO_SMEM_SIZE);
+       if((int)(ptr-(BAMBOO_BASE_VA)) < (BAMBOO_LARGE_SMEM_BOUND)) {
+               bound = (BAMBOO_SMEM_SIZE_L);
+       }
+       if((((int)(ptr-(BAMBOO_BASE_VA)))%(bound))==0) {
+               // ptr is a start of a block
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe702);
+               BAMBOO_DEBUGPRINT(1);
+#endif
+               return true;
+       }
+       if((bound-(((int)(ptr-(BAMBOO_BASE_VA)))%bound)) < (*tsize)) {
+               // it acrosses the boundary of current block
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe703);
+               BAMBOO_DEBUGPRINT(1);
+#endif
+               return true;
+       }
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0);
+#endif
+       return false;
 } // bool isLarge(void * ptr, int * ttype, int * tsize)
 
 inline int hostcore(void * ptr) {
@@ -354,11 +390,13 @@ inline void initGC() {
 
        // initialize queue
        if (gchead==NULL) {
-               gcheadindex=0;
-               gctailindex=0;
-               gctailindex2 = 0;
+               gcheadindex=gctailindex=gctailindex2 = 0;
                gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
+       } else {
+               gctailindex = gctailindex2 = gcheadindex;
+               gctail = gctail2 = gchead;
        }
+
        // initialize the large obj queues
        if (gclobjhead==NULL) {
                gclobjheadindex=0;
@@ -366,6 +404,9 @@ inline void initGC() {
                gclobjtailindex2 = 0;
                gclobjhead=gclobjtail=gclobjtail2=
                        RUNMALLOC(sizeof(struct lobjpointerblock));
+       } else {
+               gclobjtailindex = gclobjtailindex2 = gclobjheadindex;
+               gclobjtail = gclobjtail2 = gclobjhead;
        }
 } // void initGC()
 
@@ -382,15 +423,26 @@ inline int loadbalance() {
                tloads += gcloads[i];
        }
        int heaptop = BAMBOO_BASE_VA + tloads;
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xdddd);
+       BAMBOO_DEBUGPRINT_REG(tloads);
+       BAMBOO_DEBUGPRINT_REG(heaptop);
+#endif
        int b = 0;
        BLOCKINDEX(heaptop, &b);
        int numbpc = b / NUMCORES; // num of blocks per core
-
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT_REG(b);
+       BAMBOO_DEBUGPRINT_REG(numbpc);
+#endif
        gcheapdirection = (numbpc%2 == 0);
        int x = 0;
        int y = 0;
        RESIDECORE(heaptop, &x, &y);
        gctopcore = (x == 0 ? y : x * bamboo_height + y - 2);
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT_REG(gctopcore);
+#endif
        return numbpc;
 } // void loadbalance()
 
@@ -398,118 +450,217 @@ inline bool cacheLObjs() {
        // check the total mem size need for large objs
        int sumsize = 0;
        int size = 0;
-       int isize = 0;
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe801);
+#endif
+       gclobjtail2 = gclobjtail;
+       gclobjtailindex2 = gclobjtailindex;
        while(gc_lobjmoreItems2()){
                gc_lobjdequeue2();
                size = gclobjtail2->lengths[gclobjtailindex2 - 1];
-               ALIGNSIZE(size, &isize);
-               sumsize += isize;
+               sumsize += size;
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT_REG(size);
+               BAMBOO_DEBUGPRINT_REG(sumsize);
+#endif
        } // while(gc_lobjmoreItems2())
 
        // check if there are enough space to cache these large objs
-       INTPTR dst = BAMBOO_BASE_VA + BAMBOO_SHARED_MEM_SIZE - sumsize;
+       INTPTR dst = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) - sumsize;
        if(gcheaptop > dst) {
                // do not have enough room to cache large objs
                return false;
        }
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe802);
+       BAMBOO_DEBUGPRINT_REG(dst);
+#endif
 
        gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
        // cache the largeObjs to the top of the shared heap
        gclobjtail2 = gclobjtail;
-       gclobjtailindex2 = 0;
+       gclobjtailindex2 = gclobjtailindex;
        while(gc_lobjmoreItems2()) {
                gc_lobjdequeue2();
                size = gclobjtail2->lengths[gclobjtailindex2 - 1];
-               ALIGNSIZE(size, &isize);
                memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2 - 1], size);
-               // fill the remaining space with -2
-               memset(dst+size, -2, isize-size);
-               // set the new addr of this obj
-               //gclobjtail2->origs[gclobjtailindex2 - 1] = 
-               //      gclobjtail2->lobjs[gclobjtailindex2 - 1];
-               //gclobjtail2->lobjs[gclobjtailindex2 - 1] = dst;
-               dst += isize;
+               dst += size;
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
+               BAMBOO_DEBUGPRINT(dst-size);
+               BAMBOO_DEBUGPRINT_REG(size);
+#endif
        }
        return true;
 } // void cacheLObjs()
 
 inline void moveLObjs() {
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xea01);
+#endif
        // find current heap top
        // flush all gcloads to indicate the real heap top on one core
        // previous it represents the next available ptr on a core
-       if((gcloads[0] > BAMBOO_BASE_VA+BAMBOO_SMEM_SIZE_L
-                       && (gcloads[0] % BAMBOO_SMEM_SIZE == 0)) {
+       if((gcloads[0] > ((BAMBOO_BASE_VA)+(BAMBOO_SMEM_SIZE_L))
+                       && ((gcloads[0] % (BAMBOO_SMEM_SIZE)) == 0)) {
                // edge of a block, check if this is exactly the heaptop
                BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
-               gcloads[0]+=(gcfilledblocks[0]>1?BAMBOO_SMEM_SIZE:BAMBOO_SMEM_SIZE_L);
+               gcloads[0]+=(gcfilledblocks[0]>1?(BAMBOO_SMEM_SIZE):(BAMBOO_SMEM_SIZE_L));
        }
        int tmpheaptop = gcloads[0];
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+#endif
        for(int i = 1; i < NUMCORES; i++) {
-               if((gcloads[i] > BAMBOO_BASE_VA+BAMBOO_SMEM_SIZE_L
-                               && (gcloads[i] % BAMBOO_SMEM_SIZE == 0)) {
+               if((gcloads[i] > ((BAMBOO_BASE_VA)+(BAMBOO_SMEM_SIZE_L))
+                               && ((gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
                        // edge of a block, check if this is exactly the heaptop
                        BASEPTR(0, gcfilledblocks[i]-1, &gcloads[i]);
-                       gcloads[i]+=(gcfilledblocks[i]>1?BAMBOO_SMEM_SIZE:BAMBOO_SMEM_SIZE_L);
+                       gcloads[i]+=(gcfilledblocks[i]>1?(BAMBOO_SMEM_SIZE):(BAMBOO_SMEM_SIZE_L));
                }
                if(tmpheaptop < gcloads[i]) {
                        tmpheaptop = gcloads[i];
                }
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT_REG(gcloads[i]);
+               BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+#endif
        }
        // move large objs from gcheaptop to tmpheaptop
        // write the header first
-       int tomove = BAMBOO_BASE_VA + BAMBOO_SHARED_MEM_SIZE - gcheaptop;
+       int tomove = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE) - gcheaptop;
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xea02);
+       BAMBOO_DEBUGPRINT_REG(tomove);
+#endif
        if(tomove == 0) {
                gcheaptop = tmpheaptop;
                return;
        }
        // check how many blocks it acrosses
-       int b = 0;
-       BLOCKINDEX(tmpheaptop, &b);
+       int remain = tmpheaptop-(int)(BAMBOO_BASE_VA);
+       int b = remain/(BAMBOO_SMEM_SIZE);
        // check the remaining space in this block
-       int remain = (b < NUMCORES? (b+1)*BAMBOO_SMEM_SIZE_L  
-                       : BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES+1)*BAMBOO_SMEM_SIZE)
-                         -(tmpheaptop-BAMBOO_BASE_VA);
-       if(remain <= BAMBOO_CACHE_LINE_SIZE) {
-               // fill the following space with -1, go to next block
-               (*((int *)tmpheaptop)) = -1;
-               b++;
-               remain = b < NUMCORES? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-               tmpheaptop += remain;
+       int bound = (BAMBOO_SMEM_SIZE);
+       if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
+               bound = (BAMBOO_SMEM_SIZE_L);
        }
-       (*((int *)tmpheaptop)) = tomove + BAMBOO_CACHE_LINE_SIZE;
-       tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
-       memcpy(tmpheaptop, gcheaptop, tomove);
-       gcheaptop = tmpheaptop + tomove;
+       remain = bound - remain%bound;
        // flush the sbstartbl
-       memset(gcsbstarttbl, '\0', 
+       memset(&(gcsbstarttbl[gcreservedsb]), '\0', 
                           BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE*sizeof(INTPTR));
+
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xea03);
+#endif
        int size = 0;
        int isize = 0;
        int host = 0;
        int ptr = 0;
+       int base = tmpheaptop;
+       int cpysize = 0;
        remain -= BAMBOO_CACHE_LINE_SIZE;
+       tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
        while(gc_lobjmoreItems()) {
                ptr = (int)(gc_lobjdequeue(&size, &host));
                ALIGNSIZE(size, &isize);
                if(remain < isize) {
                        // this object acrosses blocks
+                       if(cpysize > 0) {
+                               // close current block, fill its header
+                               *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
+                               cpysize = 0;
+                               base = tmpheaptop;
+                               if(remain == 0) {
+                                       remain = ((tmpheaptop-(BAMBOO_BASE_VA))<(BAMBOO_LARGE_SMEM_BOUND)) ? 
+                                                      BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+                               } 
+                               remain -= BAMBOO_CACHE_LINE_SIZE;
+                               tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
+                       } // if(cpysize > 0)
+
+                       // move the large obj
+                       memcpy(tmpheaptop, gcheaptop, size);
+                       // fill the remaining space with -2 padding
+                       memset(tmpheaptop+size, -2, isize-size);
+#ifdef GC_DEBUG
+                       BAMBOO_DEBUGPRINT(0xea04);
+                       BAMBOO_DEBUGPRINT_REG(gcheaptop);
+                       BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+                       BAMBOO_DEBUGPRINT_REG(size);
+                       BAMBOO_DEBUGPRINT_REG(isize);
+#endif
+                       gcheaptop += size;
+                       if(host == BAMBOO_NUM_OF_CORE) {
+                               BAMBOO_START_CRITICAL_SECTION();
+                               RuntimeHashadd(gcpointertbl, ptr, tmpheaptop);
+                               BAMBOO_CLOSE_CRITICAL_SECTION();
+                       } else {
+                               // send the original host core with the mapping info
+                               send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop);
+                       } // if(host == BAMBOO_NUM_OF_CORE) else ...
+                       tmpheaptop += isize;
+
+                       // set the gcsbstarttbl
                        int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
-                       for(int k = 0; k < tmpsbs-1; k++) {
-                               gcsbstarttbl[k+b] = (INTPTR)(-1);
+                       for(int k = 1; k < tmpsbs; k++) {
+                               gcsbstarttbl[b+k] = (INTPTR)(-1);
                        }
                        b += tmpsbs;
-                       remain = b < NUMCORES ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-                       if((isize-remain)%BAMBOO_SMEM_SIZE == 0) {
-                               gcsbstarttbl[b+tmpsbs-1] = (INTPTR)(-1);
+                       if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
+                               gcsbstarttbl[b] = (INTPTR)(-1);
+                               remain = ((tmpheaptop-(BAMBOO_BASE_VA))<(BAMBOO_LARGE_SMEM_BOUND)) ? 
+                                                    BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
                        } else {
-                               gcsbstarttbl[b+tmpsbs-1] = (INTPTR)(tmpheaptop+isize);
-                               remain -= (isize-remain)%BAMBOO_SMEM_SIZE;
-                       }
-               }
-               // send the original host core with the mapping info
-               send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop);
-               tmpheaptop += isize;
+                               gcsbstarttbl[b] = (INTPTR)(tmpheaptop);
+                               remain = tmpheaptop-(BAMBOO_BASE_VA);
+                               int bound = remain<(BAMBOO_LARGE_SMEM_BOUND)?(BAMBOO_SMEM_SIZE_L):(BAMBOO_SMEM_SIZE);
+                               remain = bound - remain%bound;
+                       } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
+
+                       // close current block and fill the header
+                       *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
+                       cpysize = 0;
+                       base = tmpheaptop;
+                       remain -= BAMBOO_CACHE_LINE_SIZE;
+                       tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
+               } else {
+                       remain -= isize;
+                       // move the large obj
+                       memcpy(tmpheaptop, gcheaptop, size);
+                       // fill the remaining space with -2 padding
+                       memset(tmpheaptop+size, -2, isize-size);
+#ifdef GC_DEBUG
+                       BAMBOO_DEBUGPRINT(0xea05);
+                       BAMBOO_DEBUGPRINT_REG(gcheaptop);
+                       BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+                       BAMBOO_DEBUGPRINT_REG(size);
+                       BAMBOO_DEBUGPRINT_REG(isize);
+#endif
+                       gcheaptop += size;
+                       cpysize += isize;
+                       if(host == BAMBOO_NUM_OF_CORE) {
+                               BAMBOO_START_CRITICAL_SECTION();
+                               RuntimeHashadd(gcpointertbl, ptr, tmpheaptop);
+                               BAMBOO_CLOSE_CRITICAL_SECTION();
+                       } else {
+                               // send the original host core with the mapping info
+                               send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop);
+                       } // if(host == BAMBOO_NUM_OF_CORE) else ...
+                       tmpheaptop += isize;
+               } // if(remain < isize) else ...
+       } // while(gc_lobjmoreItems())
+       if(cpysize > 0) {
+               // close current block, fill the head
+               *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
+       } else {
+               tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
        }
+       gcheaptop = tmpheaptop;
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xea06);
+       BAMBOO_DEBUGPRINT_REG(gcheaptop);
+#endif
 } // void moveLObjs()
 
 inline void updateFreeMemList() {
@@ -542,6 +693,12 @@ inline void tomark(struct garbagelist * stackptr) {
        int i,j;
        // enqueue current stack 
        while(stackptr!=NULL) {
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe501);
+               BAMBOO_DEBUGPRINT_REG(stackptr->size);
+               BAMBOO_DEBUGPRINT_REG(stackptr->next);
+               BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
+#endif
                for(i=0; i<stackptr->size; i++) {
                        if(stackptr->array[i] != NULL) {
                                gc_enqueue(stackptr->array[i]);
@@ -550,6 +707,9 @@ inline void tomark(struct garbagelist * stackptr) {
                stackptr=stackptr->next;
        }
 
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe503);
+#endif
        // enqueue objectsets
        for(i=0; i<NUMCLASSES; i++) {
                struct parameterwrapper ** queues = 
@@ -568,11 +728,17 @@ inline void tomark(struct garbagelist * stackptr) {
 
        // euqueue current task descriptor
        if(currtpd != NULL) {
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe504);
+#endif
                for(i=0; i<currtpd->numParameters; i++) {
                        gc_enqueue(currtpd->parameterArray[i]);
                }
        }
 
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe505);
+#endif
        // euqueue active tasks
        struct genpointerlist * ptr=activetasks->list;
        while(ptr!=NULL) {
@@ -584,6 +750,9 @@ inline void tomark(struct garbagelist * stackptr) {
                ptr=ptr->inext;
        }
 
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe506);
+#endif
        // enqueue cached transferred obj
        struct QueueItem * tmpobjptr =  getHead(&objqueue);
        while(tmpobjptr != NULL) {
@@ -622,7 +791,6 @@ inline void mark(bool isfirst,
                                  // aligned but does not consider block boundaries
                gcmarkedptrbound = 0;
        }
-
        int isize = 0;
        // mark phase
        while(MARKPHASE == gcphase) {
@@ -637,12 +805,24 @@ inline void mark(bool isfirst,
                                // a shared obj, check if it is a local obj on this core
                                if(isLarge(ptr, &type, &size)) {
                                        // ptr is a large object
-                                       gc_lobjenqueue(ptr, size, 0);
-                                       gcnumlobjs++;
-                               } else if (isLocal(ptr)) {
-                                       // ptr is an active object on this core
+                                       if(((int *)ptr)[6] == 0) {
+                                               // not marked and not enqueued
+                                               BAMBOO_START_CRITICAL_SECTION();
+                                               gc_lobjenqueue(ptr, size, BAMBOO_NUM_OF_CORE);
+                                               gcnumlobjs++;
+                                               BAMBOO_CLOSE_CRITICAL_SECTION();
+                                               // mark this obj
+                                               ((int *)ptr)[6] = 1;
+                                       }
+                               } else if ((isLocal(ptr)) && (((int *)ptr)[6] == 0)) {
+                                       // ptr is an unmarked active object on this core
                                        ALIGNSIZE(size, &isize);
                                        gccurr_heaptop += isize;
+#ifdef GC_DEBUG
+                                       BAMBOO_DEBUGPRINT(0xaaaa);
+                                       BAMBOO_DEBUGPRINT_REG(ptr);
+                                       BAMBOO_DEBUGPRINT_REG(isize);
+#endif
                                        // mark this obj
                                        ((int *)ptr)[6] = 1;
                                        if(ptr + size > gcmarkedptrbound) {
@@ -811,8 +991,14 @@ inline void resolvePendingMoveRequest() {
                        nosparemem = true;
                        haspending = false;
                        noblock = true;
-               } 
+               }
        } // for(i = 0; i < NUMCORES; i++)
+#ifdef GCDEBUG
+       BAMBOO_DEBUGPRINT(0xcccc);
+       BAMBOO_DEBUGPRINT_REG(hasrunning);
+       BAMBOO_DEBUGPRINT_REG(haspending);
+       BAMBOO_DEBUGPRINT_REG(noblock);
+#endif
 
        if(!hasrunning && !noblock) {
                gcphase = SUBTLECOMPACTPHASE;
@@ -912,18 +1098,27 @@ inline bool moveobj(struct moveHelper * orig,
                return true;
        }
 
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe201);
+       BAMBOO_DEBUGPRINT_REG(orig->ptr);
+       BAMBOO_DEBUGPRINT_REG(to->ptr);
+#endif
+
        int type = 0;
        int size = 0;
        int mark = 0;
        int isize = 0;
 innermoveobj:
-       while((*((int*)(orig->ptr))) == -2) {
+       while((char)(*((int*)(orig->ptr))) == (char)(-2)) {
                orig->ptr++;
                if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
                        nextSBlock(orig);
                        goto innermoveobj;
                }
        }
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe202);
+#endif
        // check the obj's type, size and mark flag
        type = ((int *)(orig->ptr))[0];
        size = 0;
@@ -942,7 +1137,13 @@ innermoveobj:
                size=sizeof(struct ArrayObject)+length*elementsize;
        }
        mark = ((int *)(orig->ptr))[6];
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe203);
+#endif
        if(mark == 1) {
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe204);
+#endif
                // marked obj, copy it to current heap top
                // check to see if remaining space is enough
                ALIGNSIZE(size, &isize);
@@ -951,7 +1152,7 @@ innermoveobj:
                        if(to->top != to->bound) {
                                *((int*)to->ptr) = -1;
                        }
-                       memset(to->ptr+1, -2, to->bound - to->top - 1);
+                       //memset(to->ptr+1,  -2, to->bound - to->top - 1);
                        // fill the header of this block and then go to next block
        to->offset += to->bound - to->top;
                        (*((int*)(to->base))) = to->offset;
@@ -964,17 +1165,20 @@ innermoveobj:
                        }
                }
                memcpy(to->ptr, orig->ptr, size);
-               // restore the mark field
-               ((int *)(to->ptr))[6] = 0;
                // fill the remaining space with -2
                memset(to->ptr+size, -2, isize-size);
                // store mapping info
+               BAMBOO_START_CRITICAL_SECTION();
                RuntimeHashadd(gcpointertbl, orig->ptr, to->ptr); 
+               BAMBOO_CLOSE_CRITICAL_SECTION();
                gccurr_heaptop -= isize;
                to->ptr += isize;
                to->offset += isize;
                to->top += isize;
-       } 
+       }
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe205);
+#endif
        // move to next obj
        orig->ptr += size;
        if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
@@ -1055,6 +1259,11 @@ innercompact:
                *heaptopptr = to->ptr;
                *filledblocks = to->numblocks;
        }
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe101);
+       BAMBOO_DEBUGPRINT_REG(*heaptopptr);
+       BAMBOO_DEBUGPRINT_REG(*filledblocks);
+#endif
 
        // send msgs to core coordinator indicating that the compact is finishing
        // send compact finish message to core coordinator
@@ -1138,11 +1347,23 @@ inline void compact() {
 } // compact()
 
 inline void * flushObj(void * objptr) {
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe401);
+#endif
        void * dstptr = NULL;
        if(ISSHAREDOBJ(objptr)) {
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe402);
+               BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
                // a shared obj ptr, change to new address
+               BAMBOO_START_CRITICAL_SECTION();
                RuntimeHashget(gcpointertbl, objptr, &dstptr);
+               BAMBOO_CLOSE_CRITICAL_SECTION();
                if(NULL == dstptr) {
+#ifdef GC_DEBUG
+                       BAMBOO_DEBUGPRINT(0xe403);
+#endif
                        // send msg to host core for the mapping info
                        gcobj2map = (int)objptr;
                        gcismapped = false;
@@ -1150,53 +1371,98 @@ inline void * flushObj(void * objptr) {
                        send_msg_3(hostcore(objptr), GCMAPREQUEST, (int)objptr, 
                                                                 BAMBOO_NUM_OF_CORE);
                        while(!gcismapped) {}
+                       BAMBOO_START_CRITICAL_SECTION();
                        RuntimeHashget(gcpointertbl, objptr, &dstptr);
+                       BAMBOO_CLOSE_CRITICAL_SECTION();
                }
        } // if(ISSHAREDOBJ(objptr))
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe404);
+#endif
        return dstptr;
 } // void flushObj(void * objptr, void ** tochange)
 
 inline void flush() {
        while(gc_moreItems()) {
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT(0xe301);
+#endif
                void * ptr = gc_dequeue();
-               void * tptr = flushObj(ptr);
-               if(tptr != NULL) {
-                       ptr = tptr;
-               }
-               int type = ((int *)(ptr))[0];
-               // scan all pointers in ptr
-               unsigned INTPTR * pointer;
-               pointer=pointerarray[type];
-               if (pointer==0) {
-                       /* Array of primitives */
-                       /* Do nothing */
-               } else if (((INTPTR)pointer)==1) {
-                       /* Array of pointers */
-                       struct ArrayObject *ao=(struct ArrayObject *) ptr;
-                       int length=ao->___length___;
-                       int j;
-                       for(j=0; j<length; j++) {
-                               void *objptr=
-                                       ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
-                               ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = 
-                                       flushObj(objptr);
+#ifdef GC_DEBUG
+               BAMBOO_DEBUGPRINT_REG(ptr);
+#endif
+               if(((int *)(ptr))[6] == 1) {
+                       void * tptr = flushObj(ptr);
+#ifdef GC_DEBUG
+                       BAMBOO_DEBUGPRINT(0xe302);
+#endif
+                       if(tptr != NULL) {
+                               ptr = tptr;
                        }
-               } else {
-                       INTPTR size=pointer[0];
-                       int i;
-                       for(i=1; i<=size; i++) {
-                               unsigned int offset=pointer[i];
-                               void * objptr=*((void **)(((char *)ptr)+offset));
-                               *((void **)(((char *)ptr)+offset)) = flushObj(objptr);
-                       } // for(i=1; i<=size; i++) 
-               } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
+                       int type = ((int *)(ptr))[0];
+                       // scan all pointers in ptr
+                       unsigned INTPTR * pointer;
+                       pointer=pointerarray[type];
+#ifdef GC_DEBUG
+                       BAMBOO_DEBUGPRINT(0xe303);
+#endif
+                       if (pointer==0) {
+                               /* Array of primitives */
+                               /* Do nothing */
+                       } else if (((INTPTR)pointer)==1) {
+#ifdef GC_DEBUG
+                               BAMBOO_DEBUGPRINT(0xe304);
+#endif
+                               /* Array of pointers */
+                               struct ArrayObject *ao=(struct ArrayObject *) ptr;
+                               int length=ao->___length___;
+                               int j;
+                               for(j=0; j<length; j++) {
+#ifdef GC_DEBUG
+                                       BAMBOO_DEBUGPRINT(0xe305);
+#endif
+                                       void *objptr=
+                                               ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
+#ifdef GC_DEBUG
+                                       BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+                                       ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = 
+                                               flushObj(objptr);
+                               }
+                       } else {
+#ifdef GC_DEBUG
+                               BAMBOO_DEBUGPRINT(0xe306);
+#endif
+                               INTPTR size=pointer[0];
+                               int i;
+                               for(i=1; i<=size; i++) {
+#ifdef GC_DEBUG
+                                       BAMBOO_DEBUGPRINT(0xe307);
+#endif
+                                       unsigned int offset=pointer[i];
+                                       void * objptr=*((void **)(((char *)ptr)+offset));
+#ifdef GC_DEBUG
+                                       BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+                                       *((void **)(((char *)ptr)+offset)) = flushObj(objptr);
+                               } // for(i=1; i<=size; i++) 
+                       } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
+                       // restore the mark field, indicating that this obj has been flushed
+                       ((int *)(ptr))[6] = 0;
+               } // if(((int *)(ptr))[6] == 1)
        } // while(moi != NULL)
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe308);
+#endif
        // send flush finish message to core coordinator
        if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
                gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
        } else {
                send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE);
        }
+#ifdef GC_DEBUG
+       BAMBOO_DEBUGPRINT(0xe309);
+#endif
 } // flush()
 
 inline void gc_collect(struct garbagelist * stackptr) {
@@ -1309,8 +1575,18 @@ inline void gc(struct garbagelist * stackptr) {
                bool localcompact = true;
                while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
                        if((!finishcompact) && iscontinue) {
+#ifdef GC_DEBUG
+                               BAMBOO_DEBUGPRINT(0xe001);
+#endif
                                finishcompact = compacthelper(orig, to, &filledblocks, 
                                                                          &heaptopptr, &localcompact);
+#ifdef GC_DEBUG
+                               BAMBOO_DEBUGPRINT_REG(finishcompact);
+                               BAMBOO_DEBUGPRINT_REG(gctomove);
+                               BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
+                               BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
+                               BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
+#endif
                        }
 
                        if(gc_checkCoreStatus()) {
@@ -1325,11 +1601,20 @@ inline void gc(struct garbagelist * stackptr) {
                                if(COMPACTPHASE == gcphase) {
                                        resolvePendingMoveRequest();
                                } else {
+#ifdef GC_DEBUG
+                                       BAMBOO_DEBUGPRINT(0xe002);
+#endif
                                        compact2Heaptop();
                                }
                        } // if(gc_checkCoreStatus()) else ...
 
                        if(gctomove) {
+#ifdef GC_DEBUG
+                               BAMBOO_DEBUGPRINT(0xe003);
+                               BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
+                               BAMBOO_DEBUGPRINT_REG(gcblock2fill);
+                               BAMBOO_DEBUGPRINT_REG(gctomove);
+#endif
                                to->ptr = gcmovestartaddr;
                                to->numblocks = gcblock2fill - 1;
                                to->bound = (to->numblocks==0)?
index 16b0da6e1a42bb9fd31551c7149986c964409ab6..8cb3c158ea518362b8c6e142e792e6f9eca0f759 100644 (file)
@@ -204,7 +204,8 @@ struct Queue objqueue;
 // data structures for shared memory allocation
 #define BAMBOO_BASE_VA 0xd000000
 #ifdef GC_DEBUG
-#define BAMBOO_NUM_PAGES (1*(2+1))
+#include "structdefs.h"
+#define BAMBOO_NUM_PAGES (NUMCORES*(2+1))
 #define BAMBOO_PAGE_SIZE (16 * 16)
 #define BAMBOO_SMEM_SIZE (BAMBOO_PAGE_SIZE)
 #else
index 572479873eef784ddc8571b9d62b07af1ac70488..bc5a820b9155225551cf6acf3a869660e91c25cc 100644 (file)
@@ -119,6 +119,8 @@ void initruntimedata() {
   objqueue.head = NULL;
   objqueue.tail = NULL;
 
+       currtpd = NULL;
+
 #ifdef PROFILE
   stall = false;
   //isInterrupt = true;
@@ -140,7 +142,11 @@ void disruntimedata() {
        RUNFREE(locktable.bucket);
 #endif
        genfreehashtable(activetasks);
-       RUNFREE(currtpd);
+       if(currtpd != NULL) {
+               RUNFREE(currtpd->parameterArray);
+               RUNFREE(currtpd);
+               currtpd = NULL;
+       }
 }
 
 inline __attribute__((always_inline))
@@ -1161,12 +1167,13 @@ inline void addNewObjInfo(void * nobj) {
 void * smemalloc(int size, 
                             int * allocsize) {
        void * mem = NULL;
+       int isize = size;
 #ifdef MULTICORE_GC
        // go through free mem list for suitable blocks
        struct freeMemItem * freemem = bamboo_free_mem_list->head;
        struct freeMemItem * prev = NULL;
        do {
-               if(freemem->size >= size) {
+               if(freemem->size >= isize) {
                        // found one
                        break;
                }
@@ -1175,32 +1182,36 @@ void * smemalloc(int size,
        } while(freemem != NULL);
        if(freemem != NULL) {
                mem = (void *)(freemem->ptr);
-               *allocsize = size;
-               freemem->ptr = ((void*)freemem->ptr) + size;
-               freemem->size -= size;
-               // check how many blocks it acrosses
-               int b = 0;
-               BLOCKINDEX(mem, &b);
                // check the remaining space in this block
-               int remain = (b < NUMCORES? (b+1)*BAMBOO_SMEM_SIZE_L  
-                                       : BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES+1)*BAMBOO_SMEM_SIZE)
-                                 -((int)mem-BAMBOO_BASE_VA);
-               if(remain < size) {
+               int remain = (int)(mem-(BAMBOO_BASE_VA));
+               int bound = (BAMBOO_SMEM_SIZE);
+               if(remain < BAMBOO_LARGE_SMEM_BOUND) {
+                       bound = (BAMBOO_SMEM_SIZE_L);
+               }
+               remain = bound - remain%bound;
+               if(remain < isize) {
                        // this object acrosses blocks
-                       int tmpsbs = 1+(size-remain-1)/BAMBOO_SMEM_SIZE;
+                       // try to align the block if required a block
+                       if((isize == BAMBOO_SMEM_SIZE) && (freemem->size >= isize + remain)) {
+                               isize += remain;
+                       }
+                       /*int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
                        for(int k = 0; k < tmpsbs-1; k++) {
                                gcsbstarttbl[k+b] = (INTPTR)(-1);
                        }
-                       if((size-remain)%BAMBOO_SMEM_SIZE == 0) {
+                       if((isize-remain)%BAMBOO_SMEM_SIZE == 0) {
                                gcsbstarttbl[b+tmpsbs-1] = (INTPTR)(-1);
                        } else {
-                               gcsbstarttbl[b+tmpsbs-1] = (INTPTR)(mem+size);
-                       }
+                               gcsbstarttbl[b+tmpsbs-1] = (INTPTR)(mem+isize);
+                       }*/
                }
+               *allocsize = isize;
+               freemem->ptr = ((void*)freemem->ptr) + isize;
+               freemem->size -= isize;
        } else {
 #else
-       mem = mspace_calloc(bamboo_free_msp, 1, size);
-       *allocsize = size;
+       mem = mspace_calloc(bamboo_free_msp, 1, isize);
+       *allocsize = isize;
        if(mem == NULL) {
 #endif
                // no enough shared global memory
@@ -1933,6 +1944,7 @@ msg:
                // large obj info here
          for(int k = 5; k < msgdata[1];) {
                        gc_lobjenqueue(msgdata[k++], msgdata[k++], cnum);
+                       gcnumlobjs++;
                } // for(int k = 5; k < msgdata[1];)
                break;
        }
@@ -2406,6 +2418,7 @@ newtask:
            }
            RUNFREE(currtpd->parameterArray);
            RUNFREE(currtpd);
+                       currtpd = NULL;
            goto newtask;
          }
        } // line2865
@@ -2442,6 +2455,7 @@ newtask:
            }
            RUNFREE(currtpd->parameterArray);
            RUNFREE(currtpd);
+                       currtpd = NULL;
 #ifdef PROFILE
 #ifdef ACCURATEPROFILE
            // fail, set the end of the checkTaskInfo
@@ -2471,6 +2485,7 @@ parameterpresent:
                }
            RUNFREE(currtpd->parameterArray);
            RUNFREE(currtpd);
+                       currtpd = NULL;
            goto newtask;
          } // line2911: if (!containstag(parameter, tagd))
        } // line 2808: for(j=0; j<pd->numbertags; j++)
@@ -2483,12 +2498,12 @@ parameterpresent:
       }
 
       {
+execute:
          /* Actually call task */
 #ifdef MULTICORE_GC
          ((int *)taskpointerarray)[0]=currtpd->numParameters;
          taskpointerarray[1]=NULL;
 #endif
-execute:
 #ifdef PROFILE
 #ifdef ACCURATEPROFILE
          // check finish, set the end of the checkTaskInfo
@@ -2548,6 +2563,7 @@ execute:
          // Free up task parameter descriptor
          RUNFREE(currtpd->parameterArray);
          RUNFREE(currtpd);
+               currtpd = NULL;
 #ifdef DEBUG
          BAMBOO_DEBUGPRINT(0xe99a);
 #endif