Annotation of OpenXM_contrib2/asir2000/gc/gcj_mlc.c, Revision 1.1
1.1 ! noro 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 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 structure 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 "private/gc_pmark.h"
! 40: #include "gc_gcj.h"
! 41: #include "private/dbg_mlc.h"
! 42:
! 43: GC_bool GC_gcj_malloc_initialized = FALSE;
! 44:
! 45: int GC_gcj_kind; /* Object kind for objects with descriptors */
! 46: /* in "vtable". */
! 47: int GC_gcj_debug_kind; /* The kind of objects that is always marked */
! 48: /* with a mark proc call. */
! 49:
! 50: ptr_t * GC_gcjobjfreelist;
! 51: ptr_t * GC_gcjdebugobjfreelist;
! 52:
! 53: /* Caller does not hold allocation lock. */
! 54: void GC_init_gcj_malloc(int mp_index, void * /* really GC_mark_proc */mp)
! 55: {
! 56: register int i;
! 57: GC_bool ignore_gcj_info;
! 58: DCL_LOCK_STATE;
! 59:
! 60: GC_init(); /* In case it's not already done. */
! 61: DISABLE_SIGNALS();
! 62: LOCK();
! 63: if (GC_gcj_malloc_initialized) {
! 64: UNLOCK();
! 65: ENABLE_SIGNALS();
! 66: return;
! 67: }
! 68: GC_gcj_malloc_initialized = TRUE;
! 69: ignore_gcj_info = (0 != GETENV("GC_IGNORE_GCJ_INFO"));
! 70: # ifdef CONDPRINT
! 71: if (GC_print_stats && ignore_gcj_info) {
! 72: GC_printf0("Gcj-style type information is disabled!\n");
! 73: }
! 74: # endif
! 75: GC_mark_procs[mp_index] = (GC_mark_proc)mp;
! 76: if (mp_index >= GC_n_mark_procs) ABORT("GC_init_gcj_malloc: bad index");
! 77: /* Set up object kind gcj-style indirect descriptor. */
! 78: GC_gcjobjfreelist = (ptr_t *)
! 79: GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
! 80: if (GC_gcjobjfreelist == 0) ABORT("Couldn't allocate GC_gcjobjfreelist");
! 81: BZERO(GC_gcjobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
! 82: GC_gcj_kind = GC_n_kinds++;
! 83: GC_obj_kinds[GC_gcj_kind].ok_freelist = GC_gcjobjfreelist;
! 84: GC_obj_kinds[GC_gcj_kind].ok_reclaim_list = 0;
! 85: if (ignore_gcj_info) {
! 86: /* Use a simple length-based descriptor, thus forcing a fully */
! 87: /* conservative scan. */
! 88: GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH);
! 89: GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE;
! 90: } else {
! 91: GC_obj_kinds[GC_gcj_kind].ok_descriptor =
! 92: (((word)(-MARK_DESCR_OFFSET - GC_INDIR_PER_OBJ_BIAS))
! 93: | GC_DS_PER_OBJECT);
! 94: GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = FALSE;
! 95: }
! 96: GC_obj_kinds[GC_gcj_kind].ok_init = TRUE;
! 97: /* Set up object kind for objects that require mark proc call. */
! 98: GC_gcjdebugobjfreelist = (ptr_t *)
! 99: GC_INTERNAL_MALLOC((MAXOBJSZ+1)*sizeof(ptr_t), PTRFREE);
! 100: if (GC_gcjdebugobjfreelist == 0)
! 101: ABORT("Couldn't allocate GC_gcjdebugobjfreelist");
! 102: BZERO(GC_gcjdebugobjfreelist, (MAXOBJSZ+1)*sizeof(ptr_t));
! 103: GC_gcj_debug_kind = GC_n_kinds++;
! 104: GC_obj_kinds[GC_gcj_debug_kind].ok_freelist = GC_gcjdebugobjfreelist;
! 105: GC_obj_kinds[GC_gcj_debug_kind].ok_reclaim_list = 0;
! 106: if (ignore_gcj_info) {
! 107: GC_obj_kinds[GC_gcj_kind].ok_descriptor = (0 | GC_DS_LENGTH);
! 108: GC_obj_kinds[GC_gcj_kind].ok_relocate_descr = TRUE;
! 109: } else {
! 110: GC_obj_kinds[GC_gcj_debug_kind].ok_descriptor =
! 111: GC_MAKE_PROC(mp_index, 1 /* allocated with debug info */);
! 112: GC_obj_kinds[GC_gcj_debug_kind].ok_relocate_descr = FALSE;
! 113: }
! 114: GC_obj_kinds[GC_gcj_debug_kind].ok_init = TRUE;
! 115: UNLOCK();
! 116: ENABLE_SIGNALS();
! 117: }
! 118:
! 119: ptr_t GC_clear_stack();
! 120:
! 121: #define GENERAL_MALLOC(lb,k) \
! 122: (GC_PTR)GC_clear_stack(GC_generic_malloc_inner((word)lb, k))
! 123:
! 124: #define GENERAL_MALLOC_IOP(lb,k) \
! 125: (GC_PTR)GC_clear_stack(GC_generic_malloc_inner_ignore_off_page(lb, k))
! 126:
! 127: /* Allocate an object, clear it, and store the pointer to the */
! 128: /* type structure (vtable in gcj). */
! 129: /* This adds a byte at the end of the object if GC_malloc would.*/
! 130: void * GC_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr)
! 131: {
! 132: register ptr_t op;
! 133: register ptr_t * opp;
! 134: register word lw;
! 135: DCL_LOCK_STATE;
! 136:
! 137: if( EXPECT(SMALL_OBJ(lb), 1) ) {
! 138: # ifdef MERGE_SIZES
! 139: lw = GC_size_map[lb];
! 140: # else
! 141: lw = ALIGNED_WORDS(lb);
! 142: # endif
! 143: opp = &(GC_gcjobjfreelist[lw]);
! 144: LOCK();
! 145: op = *opp;
! 146: if( EXPECT(op == 0, 0)) {
! 147: op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
! 148: if (0 == op) {
! 149: UNLOCK();
! 150: return(GC_oom_fn(lb));
! 151: }
! 152: # ifdef MERGE_SIZES
! 153: lw = GC_size_map[lb]; /* May have been uninitialized. */
! 154: # endif
! 155: } else {
! 156: *opp = obj_link(op);
! 157: GC_words_allocd += lw;
! 158: }
! 159: *(void **)op = ptr_to_struct_containing_descr;
! 160: GC_ASSERT(((void **)op)[1] == 0);
! 161: UNLOCK();
! 162: } else {
! 163: LOCK();
! 164: op = (ptr_t)GENERAL_MALLOC((word)lb, GC_gcj_kind);
! 165: if (0 == op) {
! 166: UNLOCK();
! 167: return(GC_oom_fn(lb));
! 168: }
! 169: *(void **)op = ptr_to_struct_containing_descr;
! 170: UNLOCK();
! 171: }
! 172: return((GC_PTR) op);
! 173: }
! 174:
! 175: /* Similar to GC_gcj_malloc, but add debug info. This is allocated */
! 176: /* with GC_gcj_debug_kind. */
! 177: GC_PTR GC_debug_gcj_malloc(size_t lb, void * ptr_to_struct_containing_descr,
! 178: GC_EXTRA_PARAMS)
! 179: {
! 180: GC_PTR result;
! 181:
! 182: /* We clone the code from GC_debug_gcj_malloc, so that we */
! 183: /* dont end up with extra frames on the stack, which could */
! 184: /* confuse the backtrace. */
! 185: LOCK();
! 186: result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
! 187: if (result == 0) {
! 188: UNLOCK();
! 189: GC_err_printf2("GC_debug_gcj_malloc(%ld, 0x%lx) returning NIL (",
! 190: (unsigned long) lb,
! 191: (unsigned long) ptr_to_struct_containing_descr);
! 192: GC_err_puts(s);
! 193: GC_err_printf1(":%ld)\n", (unsigned long)i);
! 194: return(GC_oom_fn(lb));
! 195: }
! 196: *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
! 197: UNLOCK();
! 198: if (!GC_debugging_started) {
! 199: GC_start_debugging();
! 200: }
! 201: ADD_CALL_CHAIN(result, ra);
! 202: return (GC_store_debug_info(result, (word)lb, s, (word)i));
! 203: }
! 204:
! 205: /* Similar to GC_gcj_malloc, but the size is in words, and we don't */
! 206: /* adjust it. The size is assumed to be such that it can be */
! 207: /* allocated as a small object. */
! 208: void * GC_gcj_fast_malloc(size_t lw, void * ptr_to_struct_containing_descr)
! 209: {
! 210: ptr_t op;
! 211: ptr_t * opp;
! 212: DCL_LOCK_STATE;
! 213:
! 214: opp = &(GC_gcjobjfreelist[lw]);
! 215: LOCK();
! 216: op = *opp;
! 217: if( EXPECT(op == 0, 0) ) {
! 218: op = (ptr_t)GC_clear_stack(
! 219: GC_generic_malloc_words_small_inner(lw, GC_gcj_kind));
! 220: if (0 == op) {
! 221: UNLOCK();
! 222: return GC_oom_fn(WORDS_TO_BYTES(lw));
! 223: }
! 224: } else {
! 225: *opp = obj_link(op);
! 226: GC_words_allocd += lw;
! 227: }
! 228: *(void **)op = ptr_to_struct_containing_descr;
! 229: UNLOCK();
! 230: return((GC_PTR) op);
! 231: }
! 232:
! 233: /* And a debugging version of the above: */
! 234: void * GC_debug_gcj_fast_malloc(size_t lw,
! 235: void * ptr_to_struct_containing_descr,
! 236: GC_EXTRA_PARAMS)
! 237: {
! 238: GC_PTR result;
! 239: size_t lb = WORDS_TO_BYTES(lw);
! 240:
! 241: /* We clone the code from GC_debug_gcj_malloc, so that we */
! 242: /* dont end up with extra frames on the stack, which could */
! 243: /* confuse the backtrace. */
! 244: LOCK();
! 245: result = GC_generic_malloc_inner(lb + DEBUG_BYTES, GC_gcj_debug_kind);
! 246: if (result == 0) {
! 247: UNLOCK();
! 248: GC_err_printf2("GC_debug_gcj_fast_malloc(%ld, 0x%lx) returning NIL (",
! 249: (unsigned long) lw,
! 250: (unsigned long) ptr_to_struct_containing_descr);
! 251: GC_err_puts(s);
! 252: GC_err_printf1(":%ld)\n", (unsigned long)i);
! 253: return GC_oom_fn(WORDS_TO_BYTES(lw));
! 254: }
! 255: *((void **)((ptr_t)result + sizeof(oh))) = ptr_to_struct_containing_descr;
! 256: UNLOCK();
! 257: if (!GC_debugging_started) {
! 258: GC_start_debugging();
! 259: }
! 260: ADD_CALL_CHAIN(result, ra);
! 261: return (GC_store_debug_info(result, (word)lb, s, (word)i));
! 262: }
! 263:
! 264: void * GC_gcj_malloc_ignore_off_page(size_t lb,
! 265: void * ptr_to_struct_containing_descr)
! 266: {
! 267: register ptr_t op;
! 268: register ptr_t * opp;
! 269: register word lw;
! 270: DCL_LOCK_STATE;
! 271:
! 272: if( SMALL_OBJ(lb) ) {
! 273: # ifdef MERGE_SIZES
! 274: lw = GC_size_map[lb];
! 275: # else
! 276: lw = ALIGNED_WORDS(lb);
! 277: # endif
! 278: opp = &(GC_gcjobjfreelist[lw]);
! 279: LOCK();
! 280: if( (op = *opp) == 0 ) {
! 281: op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
! 282: # ifdef MERGE_SIZES
! 283: lw = GC_size_map[lb]; /* May have been uninitialized. */
! 284: # endif
! 285: } else {
! 286: *opp = obj_link(op);
! 287: GC_words_allocd += lw;
! 288: }
! 289: *(void **)op = ptr_to_struct_containing_descr;
! 290: UNLOCK();
! 291: } else {
! 292: op = (ptr_t)GENERAL_MALLOC_IOP(lb, GC_gcj_kind);
! 293: if (0 != op) {
! 294: *(void **)op = ptr_to_struct_containing_descr;
! 295: }
! 296: UNLOCK();
! 297: }
! 298: return((GC_PTR) op);
! 299: }
! 300:
! 301: #else
! 302:
! 303: char GC_no_gcj_support;
! 304:
! 305: #endif /* GC_GCJ_SUPPORT */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>