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>