6 static char *
rcsid=
"@(#)$Id$";
11 #include <sys/types.h> 12 #include <sys/times.h> 27 #define nextbuddy(p) ((bpointer)((eusinteger_t)p+(buddysize[p->h.bix]*sizeof(pointer)))) 28 #define marked(p) (p->h.mark) 29 #define markon(p) p->h.mark=1 30 #define markoff(p) p->h.mark=0 32 #define myctx (euscontexts[thr_self()]) 63 #define MAXDISPOSE 256 70 register struct chunk *cp;
72 #if defined(BIX_DEBUG) || defined(DEBUG_COUNT) 78 if (k<DEFAULTCHUNKINDEX) k=DEFAULTCHUNKINDEX;
79 if (
QDEBUG && debug) fprintf(stderr,
";; newchunk: k=%d\n",k);
86 #if Linux || Cygwin || Darwin 94 if (cp==
NULL)
return(ERR);
96 if( chunklist ==
NULL ) {
106 #if defined(RGC)// && !defined(__USE_MARK_BITMAP) 108 if (chunklist ==
NULL) {
124 cp->rootcell.h.mark=0;
125 cp->rootcell.h.smark=0;
126 cp->rootcell.h.pmark=0;
129 cp->rootcell.h.nodispose=0;
130 cp->rootcell.h.bix=k;
132 cp->rootcell.b.nextbcell=0;
134 cp->rootcell.b.nextbcell =
buddy[k].
bp;
146 cp->rootcell.h.cix = -1;
150 cp->rootcell.h.cix = -1;
161 #if defined(BIX_DEBUG) || defined(DEBUG_COUNT) 176 buddy[k-1].count +=2;
223 ctx->alloc_big_count++;
233 for (k=req;
buddy[k].
bp==0; ) k++;}
246 for (i=0; i<k; i++) b->
b.
c[i]=0;
247 ctx->lastalloc=makepointer(b);
251 printf(
"root_alloc_big: alloc 1 block (%d), 0x%lx\n", req, b );
263 {
register int i, j, k,kk;
265 register struct buddyfree *tb=ctx->thr_buddy;
266 static long buddyfill[MAXTHRBUDDY+1]={0,500,300,20,15,10,0};
274 ctx->alloc_small_count++;
277 for (i=1; i<MAXTHRBUDDY; i++) {
278 k=kk=buddyfill[i] - tb[i].
count;
312 tb[i].
count=buddyfill[i];
316 printf(
"root_alloc_small: alloc %d block(s) (%d)\n", kk, i);
329 {
register int req=1,i,ss;
335 #if defined(DEBUG) || defined(DEBUG_COUNT) 341 printf(
"alloc:%d:nils(=%d) > s(=%d)!!\n", count, nils, s );
347 printf(
"alloc:%d:s=%d, e=%d, cid=%d, nils=%d\n",
348 count, s, e, cid, nils );
352 if (tb[req].count==0) {
364 printf(
"alloc:%d:", count );
371 #if defined(DEBUG) || defined(UALLOC_DEBUG) 372 printf(
"alloc:%d:allocate for user[%d(buddysize=%d)] = 0x%lx: new list top = 0x%lx\n",
375 for (i=0; i<ss; i++) b->
b.
c[i]=0;
388 printf(
"alloc:%d:fill NIL:nils = %d, s = %d\n",
392 while (i<nils) v[i++]=
NIL;
395 while (s<i) v[s++]=
NULL;
397 printf(
"alloc:%d:after filling NIL:", count );
410 #define DEFAULT_MAX_GCSTACK 65536*2 412 #define gcpush(v) (*lgcsp++=((pointer)v)) 413 #define gcpop() (*--lgcsp) 415 #define out_of_heap(p) ((int)p<(int)_end || (pointer)0x20000000<p) 417 #if Linux || Cygwin || Darwin 418 #if (WORD_SIZE == 64) 419 #define out_of_heap(p) ((unsigned long)p<(unsigned long)minmemory || (pointer)maxmemory <p) 421 #define out_of_heap(p) ((unsigned int)p<(unsigned int)minmemory || (pointer)maxmemory <p) 426 #define out_of_heap(p) ((long)p<4 || bottom_addr<(long)p) 428 #define out_of_heap(p) ((long)p<(long)edata || (pointer)0x000003ff00000000<p) 432 #define out_of_heap(p) ((int)p<(int)edata || (pointer)0x20000000<p) 434 #if (WORD_SIZE == 64) 435 #define out_of_heap(p) ((long)p<(long)edata || (pointer)0x20000000<p) 437 #define out_of_heap(p) ((int)p<(int)edata || (pointer)0x20000000<p) 458 if (lgcsp<=gcstack)
return;
461 if (out_of_heap(p))
goto markloop;
464 if (marked(bp))
goto markloop;
467 printf(
"mark: markon 0x%lx\n", bp );
469 if (pisclosure(p))
goto markloop;
474 while (lgcsp+s>gcsplimit) {
476 for (i=0; i<
s; i++) {
478 if (ispointer(p2))
gcpush(p2); }
480 else if (bp->
h.
elmtype==ELM_POINTER) {
482 while (lgcsp+s>gcsplimit) {
484 for (i=0; i<
s; i++) {
486 if (ispointer(p2))
gcpush(p2); }
494 {
register pointer *oldstack, *stk, *newstack, *newgcsp;
495 long top, oldsize, newsize;
503 fprintf(stderr,
"\n;; extending gcstack %p[%ld] --> %p[%ld] top=%lx\n",
504 oldstack, oldsize, newstack, newsize, top);}
505 while (stk<oldsp) *newgcsp++= *stk++;
507 gcsplimit= &gcstack[newsize-10];
523 static int count = 0;
530 printf(
"markall:%d: mark(SYSTEM_OBJECTS)\n", count );
535 printf(
"markall:%d: mark(PACKAGE_LIST)\n", count );
538 for (i=0; i<MAXTHREAD; i++) {
543 printf(
"markall:%d: mark(threadobj %d)\n", count, i );
550 for (p=ctx->
stack; p<ctx->vsp; p++) {
552 #if (WORD_SIZE == 64) 562 for (j=1; j<MAXTHRBUDDY; j++) {
565 while (q) { markon(q);
567 printf(
"markall:%d: markon 0x%ld\n", count, q );
575 printf(
"markall:%d: mark(SPECIALS)\n", count );
580 if (q && ispointer(q))
582 printf(
"markall:%d: mark(lastalloc)\n", count );
587 for (i=0; i<MAXCLASS; i++) {
595 {
register int rbix,stat;
598 if (pisfilestream(s)) {
601 fprintf(stderr,
";; gc! bogus stream at %lx fd=%ld\n",
602 (
unsigned long int)s,
intval(s->c.fstream.fd));}
603 #if (WORD_SIZE == 64) 608 fprintf(stderr,
";; closing fstream was failed, %p, %d\n", s, s->
cix);
616 fprintf(stderr,
";; bad stream buffer, %p\n", s->
c.
stream.
buffer);
620 fprintf(stderr,
";; gc: dangling stream(address=%lx fd=%ld) is closed\n",
621 (
unsigned long int)s,
intval(s->c.fstream.fd)); } }
635 #if defined(DEBUG_COUNT) || defined(MERGE_DEBUG) 636 static int count = 0;
641 while (p->h.b==0 && (
int)p->h.bix<cbix) {
642 if (marked(np))
return(np);
650 printf(
"mergecell:%d:p=0x%lx, np=0x%lx\n", count, p, np );
655 printf(
"mergecell:%d:call reclaim:np=0x%lx\n", count, np );
662 register struct
chunk *cp;
666 #if defined(DEBUG_COUNT) || defined(SWEEP_DEBUG) || defined(MARK_DEBUG) 667 static int count = 0;
676 printf(
"sweep:%d:top=0x%lx, tail=0x%lx\n", count, p, tail );
680 printf(
"sweep:%d,%d:p=0x%lx:NIL->cix=%d\n", count, count2++, p,
NIL->
cix );
685 printf(
"sweep:%d,%d: markoff 0x%lx\n", count, count2, p );
693 fprintf(stderr,
"no more space for disposal processing\n");
715 if (debug) fprintf(stderr,
";; (send %p :dispose)\n", p);
716 if (a!=
NIL)
csend(ctx,p,K_DISPOSE,0);
722 register struct chunk *chp;
731 for (i=0; i<MAXBUDDY-1; i++) {
736 for (chp=chunklist; chp!=0; chp=chp->
nextchunk)
sweep(chp,gcmerge);
743 {
register int i,
self, stat;
746 for (i=0; i<MAXTHREAD; i++)
749 if (stat) fprintf(stderr,
"gc cannot suspend thread %d\n",i); }
753 {
register int i,
self, stat;
756 for (i=0; i<MAXTHREAD; i++)
759 if (stat) fprintf(stderr,
"gc cannot resume thread %d\n",i); }
766 {
if (debug) fprintf(stderr,
"\n;; gc:");
772 fprintf(stderr,
" free/total=%d/%d stack=%d ",
779 {
struct tms tbuf1,tbuf2,tbuf3;
783 if (debug) fprintf(stderr,
"\n;; gc: thread=%d ",
thr_self());
793 if (debug) fprintf(stderr,
";; gc:mutex_lock %d ", r);
803 marktime+=(tbuf2.tms_utime-tbuf1.tms_utime);
806 sweeptime+=(tbuf3.tms_utime-tbuf2.tms_utime);
815 fprintf(stderr,
" free/total=%ld/%ld stack=%d ",
837 printf(
"buddy[%d] = { %d, (", k, b[k].
count );
839 for( i = 0; i < b[k].
count; i++ ) {
840 printf(
"0x%lx ->", bp );
852 printf(
"vpush:0x%lx->[0x%lx]\n", v, ctx->
vsp );
pointer p_print(pointer v, context *ctx)
context * euscontexts[MAXTHREAD]
static void sweep(struct chunk *cp, int gcmerge)
struct filestream fstream
pointer findmethod(context *, pointer, pointer, pointer *)
void suspend_all_threads()
static pointer dispose[MAXDISPOSE]
long alloccount[MAXBUDDY]
pointer csend(context *,...)
pointer ufuncall(context *, pointer, pointer, pointer, struct bindframe *, int)
dump_bcell(int k, struct buddyfree *b)
static bpointer mergecell(bpointer p, int cbix)
void set_heap_range(unsigned int min, unsigned int max)
void newgcstack(pointer *oldsp)
void root_alloc_small(context *ctx, int req)
int rw_wrlock(rwlock_t *)
long buddysize[MAXBUDDY+1]
pointer error(enum errorcode ec,...) pointer error(va_alist) va_dcl
int rw_rdlock(rwlock_t *)
struct buddyfree buddy[MAXBUDDY+1]
int rw_unlock(rwlock_t *)
void resume_all_threads()
struct buddyfree * thr_buddy
pointer gc_alloc(int s, int e, int cid, int nils)
static eusinteger_t top_addr
static eusinteger_t bottom_addr
struct class_desc classtab[MAXCLASS]
struct bindframe * bindfp
bpointer root_alloc_big(context *ctx, int req)
void splitheap(int k, struct buddyfree *buddy)