OSDN Git Service

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