[BACK]Return to malloc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / gc5.3

Annotation of OpenXM_contrib2/asir2000/gc5.3/malloc.c, Revision 1.1.1.1

1.1       noro        1: /*
                      2:  * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
                      3:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
                      4:  *
                      5:  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
                      6:  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
                      7:  *
                      8:  * Permission is hereby granted to use or copy this program
                      9:  * for any purpose,  provided the above notices are retained on all copies.
                     10:  * Permission to modify the code and to distribute modified code is granted,
                     11:  * provided the above notices are retained, and a notice that the code was
                     12:  * modified is included with the above copyright notice.
                     13:  */
                     14: /* Boehm, February 7, 1996 4:32 pm PST */
                     15:
                     16: #include <stdio.h>
                     17: #include "gc_priv.h"
                     18:
                     19: extern ptr_t GC_clear_stack(); /* in misc.c, behaves like identity */
                     20: void GC_extend_size_map();     /* in misc.c. */
                     21:
                     22: /* Allocate reclaim list for kind:     */
                     23: /* Return TRUE on success              */
                     24: GC_bool GC_alloc_reclaim_list(kind)
                     25: register struct obj_kind * kind;
                     26: {
                     27:     struct hblk ** result = (struct hblk **)
                     28:                GC_scratch_alloc((MAXOBJSZ+1) * sizeof(struct hblk *));
                     29:     if (result == 0) return(FALSE);
                     30:     BZERO(result, (MAXOBJSZ+1)*sizeof(struct hblk *));
                     31:     kind -> ok_reclaim_list = result;
                     32:     return(TRUE);
                     33: }
                     34:
                     35: /* allocate lb bytes for an object of kind.    */
                     36: /* Should not be used to directly to allocate  */
                     37: /* objects such as STUBBORN objects that       */
                     38: /* require special handling on allocation.     */
                     39: /* First a version that assumes we already     */
                     40: /* hold lock:                                  */
                     41: ptr_t GC_generic_malloc_inner(lb, k)
                     42: register word lb;
                     43: register int k;
                     44: {
                     45: register word lw;
                     46: register ptr_t op;
                     47: register ptr_t *opp;
                     48:
                     49:     if( SMALL_OBJ(lb) ) {
                     50:         register struct obj_kind * kind = GC_obj_kinds + k;
                     51: #       ifdef MERGE_SIZES
                     52:          lw = GC_size_map[lb];
                     53: #      else
                     54:          lw = ALIGNED_WORDS(lb);
                     55:          if (lw == 0) lw = 1;
                     56: #       endif
                     57:        opp = &(kind -> ok_freelist[lw]);
                     58:         if( (op = *opp) == 0 ) {
                     59: #          ifdef MERGE_SIZES
                     60:              if (GC_size_map[lb] == 0) {
                     61:                if (!GC_is_initialized)  GC_init_inner();
                     62:                if (GC_size_map[lb] == 0) GC_extend_size_map(lb);
                     63:                return(GC_generic_malloc_inner(lb, k));
                     64:              }
                     65: #          else
                     66:              if (!GC_is_initialized) {
                     67:                GC_init_inner();
                     68:                return(GC_generic_malloc_inner(lb, k));
                     69:              }
                     70: #          endif
                     71:            if (kind -> ok_reclaim_list == 0) {
                     72:                if (!GC_alloc_reclaim_list(kind)) goto out;
                     73:            }
                     74:            op = GC_allocobj(lw, k);
                     75:            if (op == 0) goto out;
                     76:         }
                     77:         /* Here everything is in a consistent state.   */
                     78:         /* We assume the following assignment is       */
                     79:         /* atomic.  If we get aborted                  */
                     80:         /* after the assignment, we lose an object,    */
                     81:         /* but that's benign.                          */
                     82:         /* Volatile declarations may need to be added  */
                     83:         /* to prevent the compiler from breaking things.*/
                     84:        /* If we only execute the second of the         */
                     85:        /* following assignments, we lose the free      */
                     86:        /* list, but that should still be OK, at least  */
                     87:        /* for garbage collected memory.                */
                     88:         *opp = obj_link(op);
                     89:         obj_link(op) = 0;
                     90:     } else {
                     91:        register struct hblk * h;
                     92:        register word n_blocks = divHBLKSZ(ADD_SLOP(lb)
                     93:                                           + HDR_BYTES + HBLKSIZE-1);
                     94:
                     95:        if (!GC_is_initialized) GC_init_inner();
                     96:        /* Do our share of marking work */
                     97:           if(GC_incremental && !GC_dont_gc)
                     98:                GC_collect_a_little_inner((int)n_blocks);
                     99:        lw = ROUNDED_UP_WORDS(lb);
                    100:         h = GC_allochblk(lw, k, 0);
                    101: #       ifdef USE_MUNMAP
                    102:          if (0 == h) {
                    103:            GC_merge_unmapped();
                    104:            h = GC_allochblk(lw, k, 0);
                    105:          }
                    106: #      endif
                    107:        while (0 == h && GC_collect_or_expand(n_blocks, FALSE)) {
                    108:          h = GC_allochblk(lw, k, 0);
                    109:        }
                    110:        if (h == 0) {
                    111:            op = 0;
                    112:        } else {
                    113:            op = (ptr_t) (h -> hb_body);
                    114:            GC_words_wasted += BYTES_TO_WORDS(n_blocks * HBLKSIZE) - lw;
                    115:        }
                    116:     }
                    117:     GC_words_allocd += lw;
                    118:
                    119: out:
                    120:     return((ptr_t)op);
                    121: }
                    122:
                    123: ptr_t GC_generic_malloc(lb, k)
                    124: register word lb;
                    125: register int k;
                    126: {
                    127:     ptr_t result;
                    128:     DCL_LOCK_STATE;
                    129:
                    130:     GC_INVOKE_FINALIZERS();
                    131:     DISABLE_SIGNALS();
                    132:     LOCK();
                    133:     result = GC_generic_malloc_inner(lb, k);
                    134:     UNLOCK();
                    135:     ENABLE_SIGNALS();
                    136:     if (0 == result) {
                    137:         return((*GC_oom_fn)(lb));
                    138:     } else {
                    139:         return(result);
                    140:     }
                    141: }
                    142:
                    143:
                    144: #define GENERAL_MALLOC(lb,k) \
                    145:     (GC_PTR)GC_clear_stack(GC_generic_malloc((word)lb, k))
                    146: /* We make the GC_clear_stack_call a tail call, hoping to get more of  */
                    147: /* the stack.                                                          */
                    148:
                    149: /* Allocate lb bytes of atomic (pointerfree) data */
                    150: # ifdef __STDC__
                    151:     GC_PTR GC_malloc_atomic(size_t lb)
                    152: # else
                    153:     GC_PTR GC_malloc_atomic(lb)
                    154:     size_t lb;
                    155: # endif
                    156: {
                    157: register ptr_t op;
                    158: register ptr_t * opp;
                    159: register word lw;
                    160: DCL_LOCK_STATE;
                    161:
                    162:     if( SMALL_OBJ(lb) ) {
                    163: #       ifdef MERGE_SIZES
                    164:          lw = GC_size_map[lb];
                    165: #      else
                    166:          lw = ALIGNED_WORDS(lb);
                    167: #       endif
                    168:        opp = &(GC_aobjfreelist[lw]);
                    169:        FASTLOCK();
                    170:         if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
                    171:             FASTUNLOCK();
                    172:             return(GENERAL_MALLOC((word)lb, PTRFREE));
                    173:         }
                    174:         /* See above comment on signals.       */
                    175:         *opp = obj_link(op);
                    176:         GC_words_allocd += lw;
                    177:         FASTUNLOCK();
                    178:         return((GC_PTR) op);
                    179:    } else {
                    180:        return(GENERAL_MALLOC((word)lb, PTRFREE));
                    181:    }
                    182: }
                    183:
                    184: /* Allocate lb bytes of composite (pointerful) data */
                    185: # ifdef __STDC__
                    186:     GC_PTR GC_malloc(size_t lb)
                    187: # else
                    188:     GC_PTR GC_malloc(lb)
                    189:     size_t lb;
                    190: # endif
                    191: {
                    192: register ptr_t op;
                    193: register ptr_t *opp;
                    194: register word lw;
                    195: DCL_LOCK_STATE;
                    196:
                    197:     if( SMALL_OBJ(lb) ) {
                    198: #       ifdef MERGE_SIZES
                    199:          lw = GC_size_map[lb];
                    200: #      else
                    201:          lw = ALIGNED_WORDS(lb);
                    202: #       endif
                    203:        opp = &(GC_objfreelist[lw]);
                    204:        FASTLOCK();
                    205:         if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) {
                    206:             FASTUNLOCK();
                    207:             return(GENERAL_MALLOC((word)lb, NORMAL));
                    208:         }
                    209:         /* See above comment on signals.       */
                    210:         *opp = obj_link(op);
                    211:         obj_link(op) = 0;
                    212:         GC_words_allocd += lw;
                    213:         FASTUNLOCK();
                    214:         return((GC_PTR) op);
                    215:    } else {
                    216:        return(GENERAL_MALLOC((word)lb, NORMAL));
                    217:    }
                    218: }
                    219:
                    220: # ifdef REDIRECT_MALLOC
                    221: # ifdef __STDC__
                    222:     GC_PTR malloc(size_t lb)
                    223: # else
                    224:     GC_PTR malloc(lb)
                    225:     size_t lb;
                    226: # endif
                    227:   {
                    228:     /* It might help to manually inline the GC_malloc call here.       */
                    229:     /* But any decent compiler should reduce the extra procedure call  */
                    230:     /* to at most a jump instruction in this case.                     */
                    231: #   if defined(I386) && defined(SOLARIS_THREADS)
                    232:       /*
                    233:        * Thread initialisation can call malloc before
                    234:        * we're ready for it.
                    235:        * It's not clear that this is enough to help matters.
                    236:        * The thread implementation may well call malloc at other
                    237:        * inopportune times.
                    238:        */
                    239:       if (!GC_is_initialized) return sbrk(lb);
                    240: #   endif /* I386 && SOLARIS_THREADS */
                    241:     return(REDIRECT_MALLOC(lb));
                    242:   }
                    243:
                    244: # ifdef __STDC__
                    245:     GC_PTR calloc(size_t n, size_t lb)
                    246: # else
                    247:     GC_PTR calloc(n, lb)
                    248:     size_t n, lb;
                    249: # endif
                    250:   {
                    251:     return(REDIRECT_MALLOC(n*lb));
                    252:   }
                    253: # endif /* REDIRECT_MALLOC */
                    254:
                    255: GC_PTR GC_generic_or_special_malloc(lb,knd)
                    256: word lb;
                    257: int knd;
                    258: {
                    259:     switch(knd) {
                    260: #     ifdef STUBBORN_ALLOC
                    261:        case STUBBORN:
                    262:            return(GC_malloc_stubborn((size_t)lb));
                    263: #     endif
                    264:        case PTRFREE:
                    265:            return(GC_malloc_atomic((size_t)lb));
                    266:        case NORMAL:
                    267:            return(GC_malloc((size_t)lb));
                    268:        case UNCOLLECTABLE:
                    269:            return(GC_malloc_uncollectable((size_t)lb));
                    270: #       ifdef ATOMIC_UNCOLLECTABLE
                    271:          case AUNCOLLECTABLE:
                    272:            return(GC_malloc_atomic_uncollectable((size_t)lb));
                    273: #      endif /* ATOMIC_UNCOLLECTABLE */
                    274:        default:
                    275:            return(GC_generic_malloc(lb,knd));
                    276:     }
                    277: }
                    278:
                    279:
                    280: /* Change the size of the block pointed to by p to contain at least   */
                    281: /* lb bytes.  The object may be (and quite likely will be) moved.     */
                    282: /* The kind (e.g. atomic) is the same as that of the old.            */
                    283: /* Shrinking of large blocks is not implemented well.                 */
                    284: # ifdef __STDC__
                    285:     GC_PTR GC_realloc(GC_PTR p, size_t lb)
                    286: # else
                    287:     GC_PTR GC_realloc(p,lb)
                    288:     GC_PTR p;
                    289:     size_t lb;
                    290: # endif
                    291: {
                    292: register struct hblk * h;
                    293: register hdr * hhdr;
                    294: register word sz;       /* Current size in bytes       */
                    295: register word orig_sz;  /* Original sz in bytes        */
                    296: int obj_kind;
                    297:
                    298:     if (p == 0) return(GC_malloc(lb)); /* Required by ANSI */
                    299:     h = HBLKPTR(p);
                    300:     hhdr = HDR(h);
                    301:     sz = hhdr -> hb_sz;
                    302:     obj_kind = hhdr -> hb_obj_kind;
                    303:     sz = WORDS_TO_BYTES(sz);
                    304:     orig_sz = sz;
                    305:
                    306:     if (sz > WORDS_TO_BYTES(MAXOBJSZ)) {
                    307:        /* Round it up to the next whole heap block */
                    308:          register word descr;
                    309:
                    310:          sz = (sz+HDR_BYTES+HBLKSIZE-1)
                    311:                & (~HBLKMASK);
                    312:          sz -= HDR_BYTES;
                    313:          hhdr -> hb_sz = BYTES_TO_WORDS(sz);
                    314:          descr = GC_obj_kinds[obj_kind].ok_descriptor;
                    315:           if (GC_obj_kinds[obj_kind].ok_relocate_descr) descr += sz;
                    316:           hhdr -> hb_descr = descr;
                    317:          if (IS_UNCOLLECTABLE(obj_kind)) GC_non_gc_bytes += (sz - orig_sz);
                    318:          /* Extra area is already cleared by allochblk. */
                    319:     }
                    320:     if (ADD_SLOP(lb) <= sz) {
                    321:        if (lb >= (sz >> 1)) {
                    322: #          ifdef STUBBORN_ALLOC
                    323:                if (obj_kind == STUBBORN) GC_change_stubborn(p);
                    324: #          endif
                    325:            if (orig_sz > lb) {
                    326:              /* Clear unneeded part of object to avoid bogus pointer */
                    327:              /* tracing.                                             */
                    328:              /* Safe for stubborn objects.                           */
                    329:                BZERO(((ptr_t)p) + lb, orig_sz - lb);
                    330:            }
                    331:            return(p);
                    332:        } else {
                    333:            /* shrink */
                    334:              GC_PTR result =
                    335:                        GC_generic_or_special_malloc((word)lb, obj_kind);
                    336:
                    337:              if (result == 0) return(0);
                    338:                  /* Could also return original object.  But this       */
                    339:                  /* gives the client warning of imminent disaster.     */
                    340:              BCOPY(p, result, lb);
                    341: #            ifndef IGNORE_FREE
                    342:                GC_free(p);
                    343: #            endif
                    344:              return(result);
                    345:        }
                    346:     } else {
                    347:        /* grow */
                    348:          GC_PTR result =
                    349:                GC_generic_or_special_malloc((word)lb, obj_kind);
                    350:
                    351:          if (result == 0) return(0);
                    352:          BCOPY(p, result, sz);
                    353: #        ifndef IGNORE_FREE
                    354:            GC_free(p);
                    355: #        endif
                    356:          return(result);
                    357:     }
                    358: }
                    359:
                    360: # ifdef REDIRECT_MALLOC
                    361: # ifdef __STDC__
                    362:     GC_PTR realloc(GC_PTR p, size_t lb)
                    363: # else
                    364:     GC_PTR realloc(p,lb)
                    365:     GC_PTR p;
                    366:     size_t lb;
                    367: # endif
                    368:   {
                    369:     return(GC_realloc(p, lb));
                    370:   }
                    371: # endif /* REDIRECT_MALLOC */
                    372:
                    373: /* Explicitly deallocate an object p.                          */
                    374: # ifdef __STDC__
                    375:     void GC_free(GC_PTR p)
                    376: # else
                    377:     void GC_free(p)
                    378:     GC_PTR p;
                    379: # endif
                    380: {
                    381:     register struct hblk *h;
                    382:     register hdr *hhdr;
                    383:     register signed_word sz;
                    384:     register ptr_t * flh;
                    385:     register int knd;
                    386:     register struct obj_kind * ok;
                    387:     DCL_LOCK_STATE;
                    388:
                    389:     if (p == 0) return;
                    390:        /* Required by ANSI.  It's not my fault ...     */
                    391:     h = HBLKPTR(p);
                    392:     hhdr = HDR(h);
                    393: #   if defined(REDIRECT_MALLOC) && \
                    394:        (defined(SOLARIS_THREADS) || defined(LINUX_THREADS))
                    395:        /* We have to redirect malloc calls during initialization.      */
                    396:        /* Don't try to deallocate that memory.                         */
                    397:        if (0 == hhdr) return;
                    398: #   endif
                    399:     knd = hhdr -> hb_obj_kind;
                    400:     sz = hhdr -> hb_sz;
                    401:     ok = &GC_obj_kinds[knd];
                    402:     if (sz <= MAXOBJSZ) {
                    403: #      ifdef THREADS
                    404:            DISABLE_SIGNALS();
                    405:            LOCK();
                    406: #      endif
                    407:        GC_mem_freed += sz;
                    408:        /* A signal here can make GC_mem_freed and GC_non_gc_bytes      */
                    409:        /* inconsistent.  We claim this is benign.                      */
                    410:        if (IS_UNCOLLECTABLE(knd)) GC_non_gc_bytes -= WORDS_TO_BYTES(sz);
                    411:                /* Its unnecessary to clear the mark bit.  If the       */
                    412:                /* object is reallocated, it doesn't matter.  O.w. the  */
                    413:                /* collector will do it, since it's on a free list.     */
                    414:        if (ok -> ok_init) {
                    415:            BZERO((word *)p + 1, WORDS_TO_BYTES(sz-1));
                    416:        }
                    417:        flh = &(ok -> ok_freelist[sz]);
                    418:        obj_link(p) = *flh;
                    419:        *flh = (ptr_t)p;
                    420: #      ifdef THREADS
                    421:            UNLOCK();
                    422:            ENABLE_SIGNALS();
                    423: #      endif
                    424:     } else {
                    425:        DISABLE_SIGNALS();
                    426:         LOCK();
                    427:         GC_mem_freed += sz;
                    428:        if (IS_UNCOLLECTABLE(knd)) GC_non_gc_bytes -= WORDS_TO_BYTES(sz);
                    429:         GC_freehblk(h);
                    430:         UNLOCK();
                    431:         ENABLE_SIGNALS();
                    432:     }
                    433: }
                    434:
                    435: # ifdef REDIRECT_MALLOC
                    436: #   ifdef __STDC__
                    437:       void free(GC_PTR p)
                    438: #   else
                    439:       void free(p)
                    440:       GC_PTR p;
                    441: #   endif
                    442:   {
                    443: #   ifndef IGNORE_FREE
                    444:       GC_free(p);
                    445: #   endif
                    446:   }
                    447: # endif  /* REDIRECT_MALLOC */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>