void forward(universal_t *objref) { universal_t *ptr = *((universal_t **)objref); if (is_ptr(ptr) && (ptr >= curbot && ptr < curtop)) { /* ptr is a pointer into an object in fromspace */ if (is_rec(ptr)) { /* Get a pointer to the header */ universal_t *header = hdr(ptr); /* Retrieve the length of the record (plus one for the header) */ universal_t len = rec_len(ptr) + 1; /* Copy the object starting at the header into tosapce */ universal_t *i = header;; universal_t *j = endptr; while (len-- > 0) { *j++ = *i++; } /* Set the forwarding pointer in fromspace and update the record's tag */ *ptr = (universal_t)(endptr + 1); *header = UINTPTR_MAX; /* Move the end of the queue forward */ endptr = j; } /* ptr must be a forwarding pointer. It either already was, or we forwarded it above. Update the objref to point to the new object */ *objref = *(universal_t *)ptr; } }
static void event_cb(struct bufferevent *bev, short events, void *ctx) { if(events&BEV_EVENT_CONNECTED) { bufferevent_write(bev, &r1, rec_len(&r1.rec)+sizeof(record)); return; } bufferevent_free(bev); new_connection(ctx); statistics(1); }
char coq_ascii_to_char(universal_t *ptr) { assert(rec_len(ptr) == 9); unsigned char c = 0; /* Coq ascii's are represented lowest significant bit first after a constructor... */ for (int i = 8; i >= 1; i--) { c = c << 1; c |= (ptr[i] >> 1); } return (char)c; }
static void read_cb(struct bufferevent *bev, void *ctx) { state *s=(state *)ctx; int received, error=1; for(;;) { received=bufferevent_read(bev, s->buff.frag+s->ptr, s->len); if(received<=0) /* no data buffered */ return; s->ptr+=received; s->len-=received; if(s->len) /* not enough data buffered */ return; s->ptr=0; s->mode^=1; if(s->mode) { /* finished reading record header */ s->len=rec_len(&s->buff.rec); if(s->len<1 || s->len>MAX_FRAG) break; s->rec_type=s->buff.rec.type; } else { /* finished reading record fragment */ s->len=sizeof(record); if(s->rec_type==22 && s->buff.frag[0]==2) { /* handshake message type 2 (server_hello) */ bufferevent_write(bev, &r2, rec_len(&r2.rec)+sizeof(record)); bufferevent_write(bev, &r3, rec_len(&r3.rec)+sizeof(record)); bufferevent_write(bev, &r4, rec_len(&r4.rec)+sizeof(record)); } if(s->rec_type==21 && s->buff.frag[0]==2 && s->buff.frag[1]==20) { error=0; /* fatal alert 20 (bad_record_mac) */ break; } } } bufferevent_free(bev); new_connection(ctx); statistics(error); }
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 }; }
bool is_rec(universal_t *ptr) { return (rec_len(ptr) != UINTPTR_MAX); }