- #define DEBUG /* Some run-time consistency checks */
- #undef DEBUG
- #define VERBOSE
- #undef VERBOSE
- #include <stdio.h>
- #include <signal.h>
- #include "runtime.h"
- int dont_gc = 0;
- extern long mem_found;
- # ifdef MERGE_SIZES
- # if MAXOBJSZ == MAXAOBJSZ
- # define MAXSZ MAXOBJSZ
- # else
- --> causes problems here, since we cant map any size to a
- size that doesn't have a free list. Either initialization
- needs to be cleverer, or we need separate maps for atomic
- and composite objects.
- # endif
- long size_map[MAXSZ+1];
- /* Set things up so that size_map[i] >= i, but not too much bigger */
- /* and so that size_map contains relatively few distinct entries */
- void init_size_map()
- {
- register int i;
- register int i_rounded_up = 0;
- for (i = 1; i < 8; i++) {
- size_map[i] = i;
- }
- for (i = 8; i <= MAXSZ; i++) {
- if (i_rounded_up < i) {
- i_rounded_up = i + (i >> 1);
- if (i_rounded_up > MAXSZ) {
- i_rounded_up = MAXSZ;
- }
- }
- size_map[i] = i_rounded_up;
- }
- }
- # endif
- /* allocate lb bytes of atomic data */
- struct obj * gc_malloc_atomic(lb)
- int lb;
- {
- register struct obj *op;
- register struct obj **opp;
- register int lw = BYTES_TO_WORDS(lb + (sizeof (word)) -1);
- # ifdef VERBOSE
- printf("Here we are in gc_malloc_atomic(%d)n",lw);
- # endif
- if( lw <= MAXAOBJSZ ) {
- # ifdef MERGE_SIZES
- lw = size_map[lw];
- # endif
- opp = &(aobjfreelist[lw]);
- if( (op = *opp) == ((struct obj *)0) ) {
- op = allocaobj(lw);
- }
- # ifdef DEBUG
- if ((op -> obj_link != ((struct obj *) 0)
- && (((unsigned)(op -> obj_link)) > ((unsigned) HEAPLIM)
- || ((unsigned)(op -> obj_link)) < ((unsigned) HEAPSTART)))) {
- fprintf(stderr, "Bad free list in gc_malloc_atomicn");
- abort(op);
- }
- # endif
- *opp = op->obj_link;
- op->obj_link = (struct obj *)0;
- } else {
- register struct hblk * h;
- if (!sufficient_hb(-lw) && !dont_gc) {
- gcollect();
- }
- # ifdef VERBOSE
- printf("gc_malloc_atomic calling allochblk(%x)n",lw);
- # endif
- h = allochblk(-lw);
- add_hblklist(h);
- op = (struct obj *) (h -> hb_body);
- }
- return(op);
- }
- /* allocate lw bytes of possibly composite data */
- struct obj * gc_malloc(lb)
- int lb;
- {
- register struct obj *op;
- register struct obj **opp;
- register int lw = BYTES_TO_WORDS(lb + (sizeof (word)) -1);
- if( lw <= MAXOBJSZ ) {
- # ifdef MERGE_SIZES
- lw = size_map[lw];
- # endif
- opp = &(objfreelist[lw]);
- if( (op = *opp) == ((struct obj *)0) ) {
- op = allocobj(lw);
- }
- # ifdef DEBUG
- if ((op -> obj_link != ((struct obj *) 0)
- && (((unsigned)(op -> obj_link)) > ((unsigned) HEAPLIM)
- || ((unsigned)(op -> obj_link)) < ((unsigned) HEAPSTART)))) {
- fprintf(stderr, "Bad free list in gc_mallocn");
- abort(op);
- }
- # endif
- *opp = op->obj_link;
- op->obj_link = (struct obj *)0;
- } else {
- register struct hblk * h;
- if (!sufficient_hb(lw) && !dont_gc) {
- gcollect();
- }
- # ifdef VERBOSE
- printf("ralloc_comp calling allochblk(%x)n",lw);
- # endif
- h = allochblk(lw);
- add_hblklist(h);
- op = (struct obj *) (h -> hb_body);
- }
- return(op);
- }
- /* Explicitly deallocate an object p */
- gc_free(p)
- struct obj *p;
- {
- register struct hblk *h;
- register int sz;
- register word * i;
- register word * limit;
- h = HBLKPTR(p);
- sz = h -> hb_sz;
- if (sz < 0) {
- sz = -sz;
- if (sz > MAXAOBJSZ) {
- h -> hb_uninit = 1;
- del_hblklist(h);
- freehblk(h);
- } else {
- p -> obj_link = aobjfreelist[sz];
- aobjfreelist[sz] = p;
- }
- } else {
- /* Clear the object, other than link field */
- limit = &(p -> obj_component[sz]);
- for (i = &(p -> obj_component[1]); i < limit; i++) {
- *i = 0;
- }
- if (sz > MAXOBJSZ) {
- p -> obj_link = 0;
- h -> hb_uninit = 0;
- del_hblklist(h);
- freehblk(h);
- } else {
- p -> obj_link = objfreelist[sz];
- objfreelist[sz] = p;
- }
- }
- /* Add it to mem_found to prevent anomalous heap expansion */
- /* in the event of repeated explicit frees of objects of */
- /* varying sizes. */
- mem_found += sz;
- }
- /*
- * Disable non-urgent signals
- */
- int holdsigs()
- {
- unsigned mask = 0xffffffff;
- mask &= ~(1<<(SIGSEGV-1));
- mask &= ~(1<<(SIGILL-1));
- mask &= ~(1<<(SIGBUS-1));
- mask &= ~(1<<(SIGIOT-1));
- mask &= ~(1<<(SIGEMT-1));
- mask &= ~(1<<(SIGTRAP-1));
- mask &= ~(1<<(SIGQUIT-1));
- return(sigsetmask(mask));
- }
- void gc_init()
- {
- heaplim = (char *) (sbrk(0));
- # ifdef HBLK_MAP
- heapstart = (char *) (HBLKPTR(((unsigned)sbrk(0))+HBLKSIZE-1 ));
- # endif
- hincr = HINCR;
- expand_hp(hincr);
- init_hblklist();
- # ifdef MERGE_SIZES
- init_size_map();
- # endif
- }
- # ifdef MIPS
- /* There doesn't appear a reasonable way to do this under SysV.3 */
- sigsetmask() { return(0); }
- # endif