[BACK]Return to gcj_mlc.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gc

Annotation of OpenXM_contrib/gc/gcj_mlc.c, Revision 1.1.1.1

1.1       maekawa     1: /*
                      2:  * Copyright (c) 1991-1994 by Xerox Corporation.  All rights reserved.
                      3:  * Copyright (c) 1999 by Hewlett-Packard Company.  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:  */
                     15: /* Boehm, July 31, 1995 5:02 pm PDT */
                     16:
                     17: #ifdef GC_GCJ_SUPPORT
                     18:
                     19: /*
                     20:  * This is an allocator interface tuned for gcj (the GNU/Cygnus static
                     21:  * java compiler).
                     22:  *
                     23:  * Each allocated object has a pointer in its first word to a vtable,
                     24:  * which for our purposes is simply a structure describing the type of
                     25:  * the object.
                     26:  * This descriptor structur contains a GC marking descriptor at offset
                     27:  * MARK_DESCR_OFFSET.
                     28:  *
                     29:  * It is hoped that this interface may also be useful for other systems,
                     30:  * possibly with some tuning of the constants.  But the immediate goal
                     31:  * is to get better gcj performance.
                     32:  *
                     33:  * We assume:
                     34:  *  1) We have an ANSI conforming C compiler.
                     35:  *  2) Counting on explicit initialization of this interface is OK.
                     36:  *  3) FASTLOCK is not a significant win.
                     37:  */
                     38:
                     39: #include "gc_priv.h"
                     40: #include "gc_mark.h"
                     41: #include "include/gc_gcj.h"
                     42: #include "dbg_mlc.h"
                     43:
                     44: GC_bool GC_gcj_malloc_initialized = FALSE;
                     45:
                     46: int GC_gcj_kind;       /* Object kind for objects with descriptors     */
                     47:                        /* in "vtable".                                 */
                     48: int GC_gcj_debug_kind; /* The kind of objects that is always marked    */
                     49:                        /* with a mark proc call.                       */
                     50:
                     51: ptr_t * GC_gcjobjfreelist;
                     52: ptr_t * GC_gcjdebugobjfreelist;
                     53:
                     54: void * GC_default_oom_action(void) { return 0; }
                     55:
                     56: void * (*GC_oom_action)(void) = GC_default_oom_action;
                     57:
                     58: /* Caller does not hold allocation lock. */
                     59: void GC_init_gcj_malloc(int mp_index, void * /* really mark_proc */mp)
                     60: {
                     61:     register int i;
                     62:     DCL_LOCK_STATE;
                     63:
                     64:     GC_init(); /* In case it's not already done.       */
                     65:     DISABLE_SIGNALS();
                     66:     LOCK();
                     67:     if (GC_gcj_malloc_initialized) {
                     68:       UNLOCK();
                     69:       ENABLE_SIGNALS();
                     70:       return;
                     71:     }
                     72:     GC_gcj_malloc_initialized = TRUE;
                     73:     GC_mark_procs[mp_index] = (mark_proc)mp;
                     74:     if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index");
                     75:     /* Set up object kind gcj-style indirect descriptor. */
                     76:       GC_gcjobjfreelist = (ptr_t *)
                     77:           GC_generic_malloc_inner((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
                     78:       if (GC_gcjobjfreelist == 0) ABORT("Couldn't allocate GC_gcjobjfreelist");
                     79:       BZERO(GC_gcjobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
                     80:       GC_gcj_kind = GC_n_kinds++;
                     81:       GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist;
                     82:       GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0;
                     83:       GC_obj_kinds[GC_gcj_kind].ok_descriptor =
                     84:        (((word)(-MARK_DESCR_OFFSET - INDIR_PER_OBJ_BIAS)) | DS_PER_OBJECT);
                     85:       GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE;
                     86:       GC_obj_kinds[GC_gcj_kind].ok_init = TRUE;
                     87:     /* Set up object kind for objects that require mark proc call.     */
                     88:       GC_gcjdebugobjfreelist = (ptr_t *)
                     89:           GC_generic_malloc_inner((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
                     90:       if (GC_gcjdebugobjfreelist == 0)
                     91:          ABORT("Couldn't allocate GC_gcjdebugobjfreelist");
                     92:       BZERO(GC_gcjdebugobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
                     93:       GC_gcj_debug_kind = GC_n_kinds++;
                     94:       GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist;
                     95:       GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0;
                     96:       GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor =
                     97:        MAKE_PROC(mp_index, 1 /* allocated with debug info */);
                     98:       GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE;
                     99:       GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE;
                    100:     UNLOCK();
                    101:     ENABLE_SIGNALS();
                    102: }
                    103:
                    104: ptr_t GC_clear_stack();
                    105:
                    106: #define GENERAL_MALLOC(lb,k) \
                    107:     (GC_PTR)GC_clear_stack(GC_generic_malloc_inner((word)lb, k))
                    108:
                    109: #define GENERAL_MALLOC_IOP(lb,k) \
                    110:     (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k))
                    111:
                    112: /* Allocate an object, clear it, and store the pointer to the  */
                    113: /* type structure (vtable in gcj).                             */
                    114: /* This adds a byte at the end of the object if GC_malloc would.*/
                    115: void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
                    116: {
                    117: register ptr_t op;
                    118: register ptr_t * opp;
                    119: register word lw;
                    120: DCL_LOCK_STATE;
                    121:
                    122:     if( SMALL_OBJ(lb) ) {
                    123: #       ifdef MERGE_SIZES
                    124:          lw = GC_size_map[lb];
                    125: #      else
                    126:          lw = ALIGNED_WORDS(lb);
                    127: #       endif
                    128:        opp = &(GC_gcjobjfreelist[lw]);
                    129:        LOCK();
                    130:         if( (op = *opp) == 0 ) {
                    131:             op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
                    132:            if (0 == op) {
                    133:                UNLOCK();
                    134:                return(GC_oom_action());
                    135:            }
                    136: #          ifdef MERGE_SIZES
                    137:                lw = GC_size_map[lb];   /* May have been uninitialized. */
                    138: #          endif
                    139:         } else {
                    140:             *opp = obj_link(op);
                    141:             GC_words_allocd += lw;
                    142:             FASTUNLOCK();
                    143:         }
                    144:        *(void **)op = ptr_to_struct_containing_descr;
                    145:        UNLOCK();
                    146:     } else {
                    147:        LOCK();
                    148:        op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
                    149:        if (0 == op) {
                    150:            UNLOCK();
                    151:            return(GC_oom_action());
                    152:        }
                    153:        *(void **)op = ptr_to_struct_containing_descr;
                    154:        UNLOCK();
                    155:     }
                    156:     return((GC_PTR) op);
                    157: }
                    158:
                    159: /* Similar to GC_gcj_malloc, but add debug info.  This is allocated    */
                    160: /* with GC_gcj_debug_kind.                                             */
                    161: GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr,
                    162:                           GC_EXTRA_PARAMS)
                    163: {
                    164:     GC_PTR result;
                    165:
                    166:     /* We clone the code from GC_debug_gcj_malloc, so that we  */
                    167:     /* dont end up with extra frames on the stack, which could */
                    168:     /* confuse the backtrace.                                  */
                    169:     LOCK();
                    170:     result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
                    171:     if (result == 0) {
                    172:        UNLOCK();
                    173:         GC_err_printf2("GC_debug_gcj_malloc(%ld, 0x%lx) returning NIL (",
                    174:                       (unsigned long) lb,
                    175:                       (unsigned long) ptr_to_struct_containing_descr);
                    176:         GC_err_puts(s);
                    177:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    178:         return(GC_oom_action());
                    179:     }
                    180:     *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
                    181:     UNLOCK();
                    182:     if (!GC_debugging_started) {
                    183:        GC_start_debugging();
                    184:     }
                    185:     ADD_CALL_CHAIN(result, ra);
                    186:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    187: }
                    188:
                    189: /* Similar to GC_gcj_malloc, but the size is in words, and we don't    */
                    190: /* adjust it.  The size is assumed to be such that it can be   */
                    191: /* allocated as a small object.                                        */
                    192: void * GC_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr)
                    193: {
                    194: ptr_t op;
                    195: ptr_t * opp;
                    196: DCL_LOCK_STATE;
                    197:
                    198:     opp = &(GC_gcjobjfreelist[lw]);
                    199:     LOCK();
                    200:     if( (op = *opp) == 0 ) {
                    201:         op = (ptr_t)GC_clear_stack(
                    202:                GC_generic_malloc_words_small_inner(lw, GC_gcj_kind));
                    203:        if (0 == op) {
                    204:            UNLOCK();
                    205:            return(GC_oom_action());
                    206:        }
                    207:     } else {
                    208:         *opp = obj_link(op);
                    209:         GC_words_allocd += lw;
                    210:     }
                    211:     *(void **)op = ptr_to_struct_containing_descr;
                    212:     UNLOCK();
                    213:     return((GC_PTR) op);
                    214: }
                    215:
                    216: /* And a debugging version of the above:       */
                    217: void * GC_debug_gcj_fast_malloc(size_t lw,
                    218:                                void * ptr_to_struct_containing_descr,
                    219:                                GC_EXTRA_PARAMS)
                    220: {
                    221:     GC_PTR result;
                    222:     size_t lb = WORDS_TO_BYTES(lw);
                    223:
                    224:     /* We clone the code from GC_debug_gcj_malloc, so that we  */
                    225:     /* dont end up with extra frames on the stack, which could */
                    226:     /* confuse the backtrace.                                  */
                    227:     LOCK();
                    228:     result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
                    229:     if (result == 0) {
                    230:        UNLOCK();
                    231:         GC_err_printf2("GC_debug_gcj_fast_malloc(%ld, 0x%lx) returning NIL (",
                    232:                       (unsigned long) lw,
                    233:                       (unsigned long) ptr_to_struct_containing_descr);
                    234:         GC_err_puts(s);
                    235:         GC_err_printf1(":%ld)\n", (unsigned long)i);
                    236:         return(GC_oom_action());
                    237:     }
                    238:     *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
                    239:     UNLOCK();
                    240:     if (!GC_debugging_started) {
                    241:        GC_start_debugging();
                    242:     }
                    243:     ADD_CALL_CHAIN(result, ra);
                    244:     return (GC_store_debug_info(result, (word)lb, s, (word)i));
                    245: }
                    246:
                    247: void * GC_gcj_malloc_ignore_off_page(size_t lb,
                    248:                                     void * ptr_to_struct_containing_descr)
                    249: {
                    250: register ptr_t op;
                    251: register ptr_t * opp;
                    252: register word lw;
                    253: DCL_LOCK_STATE;
                    254:
                    255:     if( SMALL_OBJ(lb) ) {
                    256: #       ifdef MERGE_SIZES
                    257:          lw = GC_size_map[lb];
                    258: #      else
                    259:          lw = ALIGNED_WORDS(lb);
                    260: #       endif
                    261:        opp = &(GC_gcjobjfreelist[lw]);
                    262:        LOCK();
                    263:         if( (op = *opp) == 0 ) {
                    264:             op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
                    265: #          ifdef MERGE_SIZES
                    266:                lw = GC_size_map[lb];   /* May have been uninitialized. */
                    267: #          endif
                    268:         } else {
                    269:             *opp = obj_link(op);
                    270:             GC_words_allocd += lw;
                    271:             FASTUNLOCK();
                    272:         }
                    273:        *(void **)op = ptr_to_struct_containing_descr;
                    274:        UNLOCK();
                    275:     } else {
                    276:         op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
                    277:         if (0 != op) {
                    278:           *(void **)op = ptr_to_struct_containing_descr;
                    279:        }
                    280:         UNLOCK();
                    281:     }
                    282:     return((GC_PTR) op);
                    283: }
                    284:
                    285: #else
                    286:
                    287: char GC_no_gcj_support;
                    288:
                    289: #endif  /* GC_GCJ_SUPPORT */

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