/** * collect */ static void collect(){ // visit Roots visitGCRoots(visitor); // delete unreferenced object for(auto &elem : objects){ intptr_t intptr = (intptr_t)elem; int flag = intptr & 0x01; if(flag == 0){ std::cout << "[DELETE PTR] " << elem << " [VALUE]" << *elem << std::endl ; delete elem; } } // delete object from vector objects.erase(std::remove_if(objects.begin(), objects.end(), [](int *obj) { return ( ((intptr_t)obj & 0x01) == 0); }), objects.end()); // fix address for(auto &elem : objects){ intptr_t intptr = (intptr_t)elem; elem = (int *)--intptr; } return; }
bumpptr_t coq_gc(void) { struct timespec before; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &before); universal_t *tospace = (curbot == tobot) ? frombot : tobot; if (mprotect((void *)tospace,heapsize,PROT_READ|PROT_WRITE) != 0) fprintf(stderr, "Warning: failed to unprotect unused space\n"); /* initialize the queue in tospace */ queueptr = (curbot == frombot) ? tobot : frombot; endptr = queueptr; if (debug) { fprintf(stderr, "Starting gc collection... "); } /* Call forward on the roots */ visitGCRoots(&visitGCRoot); /* iterate the worklist until we're done copying */ while (queueptr < endptr) { universal_t *objref = queueptr+1; assert(is_rec(objref)); /* all heap allocations are records */ queueptr += rec_len(objref) + 1; do { forward(objref++); } while (objref < queueptr); } if (debug) { fprintf(stderr, "done.\n"); } /* Protect the not in use space to detect errors */ if (mprotect((void *)curbot,heapsize,PROT_NONE) != 0) { fprintf(stderr, "Warning: failed to mprotect unused space\n"); } /* Swap spaces and return the new bump pointers */ if (curtop == fromtop) { curbot = tobot; curtop = totop; } else { curbot = frombot; curtop = fromtop; } assert(curbot <= endptr && endptr <= curtop); /* Statistics */ struct timespec after; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &after); struct timespec diff; if ((after.tv_nsec-before.tv_nsec)<0) { diff.tv_sec = after.tv_sec-before.tv_sec-1; diff.tv_nsec = 1000000000+after.tv_nsec-before.tv_nsec; } else { diff.tv_sec = after.tv_sec-before.tv_sec; diff.tv_nsec = after.tv_nsec-before.tv_nsec; } collections++; collectionTime.tv_sec += diff.tv_sec; collectionTime.tv_nsec += diff.tv_nsec; if (collectionTime.tv_nsec >= 1000000000) { collectionTime.tv_nsec -= 1000000000; collectionTime.tv_sec += 1; } /* allocation starts at the end of the queue */ return (bumpptr_t) { .base = endptr, .limit = curtop }; }