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>