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);
87 fprintf(stderr,
";; can not allocate newchunk(%d)\n", k);
90 #if Linux || Cygwin || Darwin 99 if( chunklist ==
NULL ) {
109 #if defined(RGC)// && !defined(__USE_MARK_BITMAP) 111 if (chunklist ==
NULL) {
127 cp->rootcell.h.mark=0;
128 cp->rootcell.h.smark=0;
129 cp->rootcell.h.pmark=0;
132 cp->rootcell.h.nodispose=0;
133 cp->rootcell.h.bix=k;
135 cp->rootcell.b.nextbcell=0;
137 cp->rootcell.b.nextbcell =
buddy[k].
bp;
149 cp->rootcell.h.cix = -1;
153 cp->rootcell.h.cix = -1;
164 #if defined(BIX_DEBUG) || defined(DEBUG_COUNT) 179 buddy[k-1].
count +=2;
226 ctx->alloc_big_count++;
229 while (buddy[k].
bp==0) k++;
236 for (k=req; buddy[k].
bp==0; ) k++;}
245 while (req<k) {
splitheap(k--,buddy);
if (k>req) k--;}
249 for (i=0; i<k; i++) b->
b.
c[i]=0;
250 ctx->lastalloc=makepointer(b);
254 printf(
"root_alloc_big: alloc 1 block (%d), 0x%lx\n", req, b );
266 {
register int i, j, k,kk;
268 register struct buddyfree *tb=ctx->thr_buddy;
269 static long buddyfill[MAXTHRBUDDY+1]={0,500,300,20,15,10,0};
277 ctx->alloc_small_count++;
280 for (i=1; i<MAXTHRBUDDY; i++) {
281 k=kk=buddyfill[i] - tb[i].
count;
282 while (buddy[i].
count < k) {
285 while (buddy[j].
bp==0) j++;
312 tb[i].
bp=buddy[i].
bp;
314 buddy[i].
count -= kk;
315 tb[i].
count=buddyfill[i];
319 printf(
"root_alloc_small: alloc %d block(s) (%d)\n", kk, i);
332 {
register int req=1,i,ss;
338 #if defined(DEBUG) || defined(DEBUG_COUNT) 344 printf(
"alloc:%d:nils(=%d) > s(=%d)!!\n", count, nils,
s );
350 printf(
"alloc:%d:s=%d, e=%d, cid=%d, nils=%d\n",
351 count,
s, e, cid, nils );
355 if (tb[req].count==0) {
367 printf(
"alloc:%d:", count );
374 #if defined(DEBUG) || defined(UALLOC_DEBUG) 375 printf(
"alloc:%d:allocate for user[%d(buddysize=%d)] = 0x%lx: new list top = 0x%lx\n",
378 for (i=0; i<ss; i++) b->
b.
c[i]=0;
391 printf(
"alloc:%d:fill NIL:nils = %d, s = %d\n",
395 while (i<nils) v[i++]=
NIL;
400 printf(
"alloc:%d:after filling NIL:", count );
413 #define DEFAULT_MAX_GCSTACK 65536*2 415 #define gcpush(v) (*lgcsp++=((pointer)v)) 416 #define gcpop() (*--lgcsp) 418 #define out_of_heap(p) ((int)p<(int)_end || (pointer)0x20000000<p) 420 #if Linux || Cygwin || Darwin 421 #if (WORD_SIZE == 64) 422 #define out_of_heap(p) ((unsigned long)p<(unsigned long)minmemory || (pointer)maxmemory <p) 424 #define out_of_heap(p) ((unsigned int)p<(unsigned int)minmemory || (pointer)maxmemory <p) 429 #define out_of_heap(p) ((long)p<4 || bottom_addr<(long)p) 431 #define out_of_heap(p) ((long)p<(long)edata || (pointer)0x000003ff00000000<p) 435 #define out_of_heap(p) ((int)p<(int)edata || (pointer)0x20000000<p) 437 #if (WORD_SIZE == 64) 438 #define out_of_heap(p) ((long)p<(long)edata || (pointer)0x20000000<p) 440 #define out_of_heap(p) ((int)p<(int)edata || (pointer)0x20000000<p) 461 if (lgcsp<=gcstack)
return;
464 if (out_of_heap(p))
goto markloop;
467 if (marked(bp))
goto markloop;
470 printf(
"mark: markon 0x%lx\n", bp );
472 if (pisclosure(p))
goto markloop;
477 while (lgcsp+s>gcsplimit) {
479 for (i=0; i<
s; i++) {
481 if (ispointer(p2))
gcpush(p2); }
483 else if (bp->
h.
elmtype==ELM_POINTER) {
485 while (lgcsp+s>gcsplimit) {
487 for (i=0; i<
s; i++) {
489 if (ispointer(p2))
gcpush(p2); }
497 {
register pointer *oldstack, *stk, *newstack, *newgcsp;
498 long top, oldsize, newsize;
506 fprintf(stderr,
"\n;; extending gcstack %p[%ld] --> %p[%ld] top=%lx\n",
507 oldstack, oldsize, newstack, newsize, top);}
508 while (stk<oldsp) *newgcsp++= *stk++;
510 gcsplimit= &gcstack[newsize-10];
526 static int count = 0;
533 printf(
"markall:%d: mark(SYSTEM_OBJECTS)\n", count );
538 printf(
"markall:%d: mark(PACKAGE_LIST)\n", count );
541 for (i=0; i<MAXTHREAD; i++) {
546 printf(
"markall:%d: mark(threadobj %d)\n", count, i );
553 for (p=ctx->
stack; p<ctx->vsp; p++) {
555 #if (WORD_SIZE == 64) 565 for (j=1; j<MAXTHRBUDDY; j++) {
568 while (q) { markon(q);
570 printf(
"markall:%d: markon 0x%ld\n", count, q );
578 printf(
"markall:%d: mark(SPECIALS)\n", count );
583 if (q && ispointer(q))
585 printf(
"markall:%d: mark(lastalloc)\n", count );
590 for (i=0; i<MAXCLASS; i++) {
598 {
register int rbix,stat;
601 if (pisfilestream(s)) {
604 fprintf(stderr,
";; gc! bogus stream at %lx fd=%ld\n",
605 (
unsigned long int)s,
intval(s->c.fstream.fd));}
606 #if (WORD_SIZE == 64) 611 fprintf(stderr,
";; closing fstream was failed, %p, %d\n", s, s->
cix);
619 fprintf(stderr,
";; bad stream buffer, %p\n", s->
c.
stream.
buffer);
623 fprintf(stderr,
";; gc: dangling stream(address=%lx fd=%ld) is closed\n",
624 (
unsigned long int)s,
intval(s->c.fstream.fd)); } }
627 p->b.nextbcell=buddy[rbix].
bp;
628 buddy[rbix].
bp=p; buddy[rbix].
count++;
638 #if defined(DEBUG_COUNT) || defined(MERGE_DEBUG) 639 static int count = 0;
644 while (p->h.b==0 && (
int)p->h.bix<cbix) {
645 if (marked(np))
return(np);
653 printf(
"mergecell:%d:p=0x%lx, np=0x%lx\n", count, p, np );
658 printf(
"mergecell:%d:call reclaim:np=0x%lx\n", count, np );
665 register struct chunk *cp;
669 #if defined(DEBUG_COUNT) || defined(SWEEP_DEBUG) || defined(MARK_DEBUG) 670 static int count = 0;
679 printf(
"sweep:%d:top=0x%lx, tail=0x%lx\n", count, p, tail );
683 printf(
"sweep:%d,%d:p=0x%lx:NIL->cix=%d\n", count, count2++, p,
NIL->
cix );
688 printf(
"sweep:%d,%d: markoff 0x%lx\n", count, count2, p );
696 fprintf(stderr,
"no more space for disposal processing\n");
718 if (debug) fprintf(stderr,
";; (send %p :dispose)\n", p);
719 if (a!=
NIL)
csend(ctx,p,K_DISPOSE,0);
725 register struct chunk *chp;
734 for (i=0; i<MAXBUDDY-1; i++) {
739 for (chp=chunklist; chp!=0; chp=chp->
nextchunk)
sweep(chp,gcmerge);
746 {
register int i,
self, stat;
749 for (i=0; i<MAXTHREAD; i++)
752 if (stat) fprintf(stderr,
"gc cannot suspend thread %d\n",i); }
756 {
register int i,
self, stat;
759 for (i=0; i<MAXTHREAD; i++)
762 if (stat) fprintf(stderr,
"gc cannot resume thread %d\n",i); }
769 {
if (debug) fprintf(stderr,
"\n;; gc:");
775 fprintf(stderr,
" free/total=%d/%d stack=%d ",
782 {
struct tms tbuf1,tbuf2,tbuf3;
786 if (debug) fprintf(stderr,
"\n;; gc: thread=%d ",
thr_self());
796 if (debug) fprintf(stderr,
";; gc:mutex_lock %d ", r);
806 marktime+=(tbuf2.tms_utime-tbuf1.tms_utime);
809 sweeptime+=(tbuf3.tms_utime-tbuf2.tms_utime);
818 fprintf(stderr,
" free/total=%ld/%ld stack=%d ",
840 printf(
"buddy[%d] = { %d, (", k, b[k].
count );
842 for( i = 0; i < b[k].
count; i++ ) {
843 printf(
"0x%lx ->", bp );
855 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)
euspointer_t mark_stack_root
struct filestream fstream
pointer findmethod(context *, pointer, pointer, pointer *)
void suspend_all_threads()
unsigned long euspointer_t
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)
euspointer_t mark_buddy_q
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)