Example #1
0
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;
  }
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #4
0
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);
}
Example #5
0
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 };
}
Example #6
0
bool is_rec(universal_t *ptr) {
    return (rec_len(ptr) != UINTPTR_MAX);
}