[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     ! 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>