📄 snap_io.c
字号:
case NEQI: case SVCV: case CALLS: newhalloc = scan_value(&(codedst->arg), p->heap_min, p->heap_max, p->stack_max, p->h_alloc_heap_max, newhmin, newhalloc, newhmax); break; default: break; } /* end switch */#endif codedst++; } /* end while */ } d_printf(150,"%s:%d: done scanning code\n",__FILE__,__LINE__); /* copy stack */ d_printf(150,"%s:%d: scanning stack\n",__FILE__,__LINE__); { int sizeb = (int)((void *)p->sp - (void *)stacksrc); value_t *stackmax = (value_t *)((void *)stackdst + sizeb); memcpy(stackdst,stacksrc,sizeb); while (stackdst < stackmax) { newhalloc = scan_value(stackdst, p->heap_min, p->heap_max, p->stack_max, p->h_alloc_heap_max, newhmin, newhalloc, newhmax); stackdst++; } } d_printf(150,"%s:%d: done scanning stack\n",__FILE__,__LINE__); /* scan the topspace heap, copying any reachable, uncopied objects */ d_printf(150,"%s:%d: scanning heap, @%#x to @%#x\n", __FILE__,__LINE__,(unsigned int)newhscan,(unsigned int)newhalloc); while (newhscan < newhalloc) { heap_obj *hsrc = (heap_obj *)newhscan; int sizeb = sizeof(heap_obj) + hsrc->len; /* note that we can assume that hsrc->len is within the heap since it was copied here by the GC. */ if ((sizeb & 0x3) != 0) { sizeb = (sizeb & ~0x3) + 4; } /* if contains pointers, scan the contents of the object */ /* note we check for ==1 exactly in case this object is bogus (don't want to scan a bogus object, just skip it) */ if (hsrc->flag == 1) { value_t *vsrc = (value_t *)hsrc->s, *vsrcend = (value_t *)(hsrc->s + hsrc->len); while (vsrc < vsrcend) { newhalloc = scan_value(vsrc, p->heap_min, p->heap_max, p->stack_max, p->h_alloc_heap_max, newhmin, newhalloc, newhmax); vsrc++; } } newhscan += sizeb; } d_printf(150,"%s:%d: done scanning heap\n",__FILE__,__LINE__); /* compress the heap */ if (newhalloc != newhmax) { d_printf(150,"%s:%d: compressing heap/sliding stack down\n", __FILE__,__LINE__); memmove(newhalloc,newhmax,(stack_amt * sizeof(value_t))); stackdst = (value_t *)((void *)stackdst - (newhmax - newhalloc)); } /* remove forwarding pointers from current packet's heap */ d_printf(150,"%s:%d: removing forwarding pointers from current packet\n", __FILE__,__LINE__); reset_heap(p,newhmin,newhalloc); /* note sizes of various things in the new packet */ assert((void *)p->code_max > (void *)p->code_min); newhdr->code_sizeb = htons((void *)p->code_max - (void *)p->code_min); assert(stack_amt >= 0); newhdr->stack_sizeb = htons(stack_amt * sizeof(value_t)); assert(newhalloc >= newhmin); newhdr->heap_sizeb = htons(newhalloc - newhmin); { int actual_sizeb = sizeof(struct iphdr) + 4 + sizeof(struct snaphdr) + ntohs(newhdr->code_sizeb) + ntohs(newhdr->stack_sizeb) + ntohs(newhdr->heap_sizeb); struct iphdr *newiph = (struct iphdr *)io_outbuf; newiph->tot_len = htons(actual_sizeb); } d_printf(25,"%s:%d: newcs=%d newss=%d newhs=%d\n",__FILE__,__LINE__, ntohs(newhdr->code_sizeb), ntohs(newhdr->stack_sizeb), ntohs(newhdr->heap_sizeb)); bufstr->lenb = (void *)stackdst - (void *)io_outbuf; bufstr->s = io_outbuf; print_timer(8,"marshal_packet"); return 0;}/* invariants (pre and post conditions): tohalloc and tohmax are word-aligned tohalloc <= tohmax tohalloc >= tohmin hsrc is within fromspace heap, sizeb = hsrc->len + sizeof(heap_obj) rounded up to word boundary*/static void *copy_heap_obj(heap_obj *hsrc, int sizeb, void *tohmin, void *tohalloc, void *tohmax) { heap_obj *hdst; d_printf(150,"%s:%d: heap obj @%#x (size:%d,f:%d) --", __FILE__,__LINE__,(uint32)hsrc,hsrc->len,hsrc->flag); /* check 2, rather than 4, to avoid copying heap objs that have bogus flag values of 2 and 3 */ if (hsrc->flag < 2) { /* not forwarded yet, do it now */ hdst = (heap_obj *)tohalloc; tohalloc += sizeb; /* this check will only succeed if we're processing a bogus object. */ if (tohalloc > tohmax) { fprintf(stderr,"%s:%d: Warning, processed bogus object, @%#x\n", __FILE__,__LINE__,(unsigned int)hsrc); /* don't do the copy */ return (void *)hdst; } hdst->len = hsrc->len; /* now is essentially "legal", thanks to check */ hdst->flag = hsrc->flag; /* may be bogus */ memcpy(&(hdst->s),&(hsrc->s),hsrc->len); /* XXX switch to word-aligned offsets ? */ assert((tohalloc - tohmin + 4) <= 65536); /* forward it, add 4 to diff from legal flag val 0 */ hsrc->flag = (void *)hdst - tohmin + 4; d_printf(150,"copied to offs %d, @%#x\n", hsrc->flag - 4, (unsigned int)hdst); }#ifndef NDEBUG else d_printf(150,"forwarded with offs %d, @%#x\n", hsrc->flag - 4,(unsigned int)(tohmin + (hsrc->flag - 4)));#endif return(tohalloc);}/* invariants (pre and post conditions): tohalloc and tohmax are word-aligned tohalloc <= tohmax tohalloc >= tohmin if the stack value is a bogus pointer (i.e., it might point outside the heap, or it might be too big), then it will also be bogus on the way out (in fact, it will be some very large integer).*/static void *scan_value(value_t *v, void *fromh, void *fromhmax, void *fromhalloc, void *fromhallocmax, void *tohmin, void *tohalloc, void *tohmax) { switch(GET_TAG(*v)) { case INTV: case EXCV: default: break; case ADDRV: case FLOATV:#ifndef ADDR_IN_HEAP break;#endif case STRV: case TUPLEV: { int sizeb; heap_obj *hsrc = (heap_obj *)(fromh + GET_OFFS(*v)); /* make sure it's in the fromspace heap */ IF_IN_FROM_HEAP(hsrc,sizeb,fromh,fromhmax,fromhalloc,fromhallocmax) { tohalloc = copy_heap_obj(hsrc,sizeb,tohmin,tohalloc,tohmax); /* apply forwarding pointer */ SET_OFFS(*v,hsrc->flag - 4); /* subtract the extra 4 from the offset */ assert(GET_OFFS(*v) == (hsrc->flag - 4)); wassert(GET_OFFS(*v) >= 0); wassert((GET_OFFS(*v) % 4) == 0); } /* otherwise, set the value to a NULL */ ELSE_NOT_IN_FROM_HEAP { fprintf (stderr,"%s:%d: warning, pointer @%#x not in heap, NULLing\n", __FILE__,__LINE__,(unsigned int)hsrc); SET_TAG(*v,INTV); SET_INT(*v,0); } break; } } return(tohalloc);}static void clear_forw_offs(value_t *v, void *fromh, void *fromhmax, void *fromhalloc, void *fromhallocmax, void *toh, void *tohmax);/* invariant: hsrc is the fromspace heap postcond: hsrc->flag = 0 or 1 (prevents GC loops) */static void reset_heap_obj(heap_obj *hsrc, void *fromh, void *fromhmax, void *fromhalloc, void *fromhallocmax, void *toh, void *tohmax) { /* check >= 2 (rather than 4) to process bogus pointers */ if (hsrc->flag >= 2) { heap_obj *hdst; int sizeb = sizeof(heap_obj) + hsrc->len; if ((sizeb & 0x3) != 0) { sizeb = (sizeb & ~0x3) + 4; } wassert((hsrc->flag % 4) == 0); hdst = (heap_obj *)(toh + hsrc->flag - 4); /* make sure the object is in the tospace heap */ if (IN_TOSPACE_HEAP(hdst,sizeb,toh,tohmax)) { /* restore the old flag value, removing the forwarding offs */ /* note we need to set the flag to 0 here to in case the hsrc flag was bogus and happened to point to tospace. */ hsrc->flag = (hdst->flag == 1 ? 1 : 0); /* scan the object, if necessary, and recurse */ if (hsrc->flag) { value_t *vsrc = (value_t *)hsrc->s, *vsrcend = (value_t *)(hsrc->s + hsrc->len); while (vsrc < vsrcend) { clear_forw_offs(vsrc, fromh, fromhmax, fromhalloc, fromhallocmax, toh, tohmax); vsrc++; } } /* doesn't contain pointers, don't scan */ } /* bogus pointer, leave it */ else { fprintf (stderr,"%s:%d: warning, forw offs to @%#x not in heap\n", __FILE__,__LINE__,(unsigned int)hdst); } } /* else nothing to do */}static void clear_forw_offs(value_t *v, void *fromh, void *fromhmax, void *fromhalloc, void *fromhallocmax, void *toh, void *tohmax) { switch(GET_TAG(*v)) { case INTV: case EXCV: default: break; case ADDRV: case FLOATV:#ifndef ADDR_IN_HEAP break;#endif case STRV: case TUPLEV: { heap_obj *hsrc = (heap_obj *)(fromh + GET_OFFS(*v)); int sizeb; IF_IN_FROM_HEAP(hsrc,sizeb,fromh,fromhmax, fromhalloc,fromhallocmax) reset_heap_obj(hsrc,fromh,fromhmax, fromhalloc,fromhallocmax, toh,tohmax); ELSE_NOT_IN_FROM_HEAP { fprintf (stderr,"%s:%d: warning, pointer @%#x not in heap\n", __FILE__,__LINE__,(unsigned int)hsrc); } } }}/* clears all of the forwarding pointers left by the marshalling process */static void reset_heap(packet_t *p, void *to_heap, void *to_heap_max) { instr_t *codesrc = p->code_min; value_t *stacksrc = p->stack_min; while (codesrc < p->code_max) {#ifdef SMALL_INSTRS switch (GET_OP(*codesrc)) { case SVCV: case CALLS: case PSTR: case EQSTR: case NQSTR: case PTUP: case EQTUP: case NQTUP: case PADDR: case EQADR: case NQADR: case FGTI: case FGEQI: case FLEQI: case FLTI: case FADDI: case FSUBI: case FMULI: case FDIVI: case SNETI: case BCASTI: { int hoffs, sizeb; heap_obj *hsrc; GET_LIT(hoffs,BOGUSV,*codesrc); hsrc = (heap_obj *)(p->heap_min + hoffs); IF_IN_FROM_HEAP(hsrc,sizeb,p->heap_min,p->heap_max, p->stack_max,p->h_alloc_heap_max) { reset_heap_obj(hsrc, p->heap_min, p->heap_max, p->stack_max, p->h_alloc_heap_max, to_heap, to_heap_max); } ELSE_NOT_IN_FROM_HEAP { fprintf (stderr,"%s:%d: warning, pointer @%#x not in heap\n", __FILE__,__LINE__,(unsigned int)hsrc); } break; } default: break; } /* end switch */#else switch (GET_OP(*codesrc)) {#ifdef ADDR_IN_HEAP case SNETI: case BCASTI: /* these may contain floating point values */ case GTI: case GEQI: case LTI: case LEQI: case ADDI: case SUBI: case MULTI: case DIVI:#endif case PUSH: case EQI: case NEQI: case SVCV: case CALLS: clear_forw_offs(&(codesrc->arg), p->heap_min, p->heap_max, p->stack_max, p->h_alloc_heap_max, to_heap, to_heap_max); break; default: break; } /* end switch */#endif codesrc++; } while (stacksrc < p->sp) { clear_forw_offs(stacksrc, p->heap_min, p->heap_max, p->stack_max, p->h_alloc_heap_max, to_heap, to_heap_max); stacksrc++; } /* no need to scan the heap; this was done recursively while scanning the stack */}int file_to_str(int fd, buffer_t *buf) { int bufinc = 1024; int newlen; char *newbuf; char *inptr; int bytes_read; int total_bytes_read = 0; memalloc(buf->s, char *, bufinc); buf->lenb = bufinc; inptr = buf->s; while(1) { int space_left = buf->lenb - (inptr - buf->s); bytes_read = read(fd,inptr,space_left); if (bytes_read == -1 && (errno == EINTR || errno == EAGAIN)) continue; total_bytes_read += bytes_read; if (bytes_read == space_left) { newlen = buf->lenb + bufinc; memalloc(newbuf, char *, newlen); memcpy(newbuf,buf->s,buf->lenb); inptr = newbuf + buf->lenb; buf->lenb = newlen; free(buf->s); buf->s = newbuf; continue; } /* buf->lenb = (inptr - buf->s) + bytes_read; */ break; } return total_bytes_read;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -