* parse-scan.y (interface_declaration): Call
[official-gcc.git] / libjava / boehm.cc
blobc41dab94387ca1df21052da53931eb291d49a5b9
1 // boehm.cc - interface between libjava and Boehm GC.
3 /* Copyright (C) 1998, 1999 Cygnus Solutions
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 #include <config.h>
13 #include <stdio.h>
15 #include <cni.h>
16 #include <java/lang/Class.h>
17 #include <jvm.h>
18 #include <java-field.h>
20 // We need to include gc_priv.h. However, it tries to include
21 // config.h if it hasn't already been included. So we force the
22 // inclusion of the Boehm config.h.
23 extern "C"
25 #include <boehm-config.h>
26 #include <gc_priv.h>
27 #include <gc_mark.h>
29 // These aren't declared in any Boehm GC header.
30 void GC_finalize_all (void);
31 ptr_t GC_debug_generic_malloc (size_t size, int k, GC_EXTRA_PARAMS);
34 // FIXME: this should probably be defined in some GC header.
35 #ifdef GC_DEBUG
36 # define GC_GENERIC_MALLOC(Size, Type) \
37 GC_debug_generic_malloc (Size, Type, GC_EXTRAS)
38 #else
39 # define GC_GENERIC_MALLOC(Size, Type) GC_generic_malloc (Size, Type)
40 #endif
42 // We must check for plausibility ourselves.
43 #define MAYBE_MARK(Obj, Top, Limit, Source, Exit) \
44 if ((ptr_t) (Obj) >= GC_least_plausible_heap_addr \
45 && (ptr_t) (Obj) <= GC_greatest_plausible_heap_addr) \
46 PUSH_CONTENTS (Obj, Top, Limit, Source, Exit)
48 #define ObjectClass _CL_Q34java4lang6Object
49 extern java::lang::Class ObjectClass;
50 #define ClassClass _CL_Q34java4lang5Class
51 extern java::lang::Class ClassClass;
55 // Nonzero if this module has been initialized.
56 static int initialized = 0;
58 // `kind' index used when allocating Java objects.
59 static int obj_kind_x;
61 // `kind' index used when allocating Java arrays.
62 static int array_kind_x;
64 // Freelist used for Java objects.
65 static ptr_t *obj_free_list;
67 // Freelist used for Java arrays.
68 static ptr_t *array_free_list;
72 // This is called by the GC during the mark phase. It marks a Java
73 // object. We use `void *' arguments and return, and not what the
74 // Boehm GC wants, to avoid pollution in our headers.
75 void *
76 _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
78 mse *mark_stack_ptr = (mse *) msp;
79 mse *mark_stack_limit = (mse *) msl;
80 jobject obj = (jobject) addr;
82 _Jv_VTable *dt = *(_Jv_VTable **) addr;
83 // We check this in case a GC occurs before the vtbl is set. FIXME:
84 // should use allocation lock while initializing object.
85 if (! dt)
86 return mark_stack_ptr;
87 jclass klass = dt->clas;
89 // Every object has a sync_info pointer.
90 word w = (word) obj->sync_info;
91 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, o1label);
92 // Mark the object's class.
93 w = (word) klass;
94 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, o2label);
96 if (klass == &ClassClass)
98 jclass c = (jclass) addr;
100 w = (word) c->next;
101 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c2label);
102 w = (word) c->name;
103 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c3label);
104 w = (word) c->superclass;
105 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c4label);
106 for (int i = 0; i < c->constants.size; ++i)
108 w = (word) c->constants.data[i];
109 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5label);
112 // If the class is an array, then the methods field holds a
113 // pointer to the element class. If the class is primitive,
114 // then the methods field holds a pointer to the array class.
115 w = (word) c->methods;
116 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c6label);
118 if (! c->isArray() && ! c->isPrimitive())
120 // Scan each method in the cases where `methods' really
121 // points to a methods structure.
122 for (int i = 0; i < c->method_count; ++i)
124 w = (word) c->methods[i].name;
125 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
126 cm1label);
127 w = (word) c->methods[i].signature;
128 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
129 cm2label);
130 // FIXME: `ncode' entry?
134 // Mark all the fields.
135 w = (word) c->fields;
136 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8label);
137 for (int i = 0; i < c->field_count; ++i)
139 #ifndef COMPACT_FIELDS
140 w = (word) c->fields[i].name;
141 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8alabel);
142 #endif
143 w = (word) c->fields[i].type;
144 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8blabel);
147 w = (word) c->vtable;
148 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c9label);
149 w = (word) c->interfaces;
150 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cAlabel);
151 for (int i = 0; i < c->interface_count; ++i)
153 w = (word) c->interfaces[i];
154 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cClabel);
156 w = (word) c->loader;
157 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cBlabel);
159 else
161 // NOTE: each class only holds information about the class
162 // itself. So we must do the marking for the entire inheritance
163 // tree in order to mark all fields. FIXME: what about
164 // interfaces? We skip Object here, because Object only has a
165 // sync_info, and we handled that earlier.
166 // Note: occasionally `klass' can be null. For instance, this
167 // can happen if a GC occurs between the point where an object
168 // is allocated and where the vtbl slot is set.
169 while (klass && klass != &ObjectClass)
171 jfieldID field = JvGetFirstInstanceField (klass);
172 jint max = JvNumInstanceFields (klass);
174 for (int i = 0; i < max; ++i)
176 if (JvFieldIsRef (field))
178 jobject val = JvGetObjectField (obj, field);
179 w = (word) val;
180 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit,
181 obj, elabel);
183 field = field->getNextInstanceField ();
185 klass = klass->getSuperclass();
189 return mark_stack_ptr;
192 // This is called by the GC during the mark phase. It marks a Java
193 // array (of objects). We use `void *' arguments and return, and not
194 // what the Boehm GC wants, to avoid pollution in our headers.
195 void *
196 _Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/)
198 mse *mark_stack_ptr = (mse *) msp;
199 mse *mark_stack_limit = (mse *) msl;
200 jobjectArray array = (jobjectArray) addr;
202 _Jv_VTable *dt = *(_Jv_VTable **) addr;
203 // We check this in case a GC occurs before the vtbl is set. FIXME:
204 // should use allocation lock while initializing object.
205 if (! dt)
206 return mark_stack_ptr;
207 jclass klass = dt->clas;
209 // Every object has a sync_info pointer.
210 word w = (word) array->sync_info;
211 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, array, e1label);
212 // Mark the object's class.
213 w = (word) klass;
214 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, o2label);
216 for (int i = 0; i < JvGetArrayLength (array); ++i)
218 jobject obj = elements (array)[i];
219 w = (word) obj;
220 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, array, e2label);
223 return mark_stack_ptr;
226 // Allocate space for a new Java object. FIXME: this might be the
227 // wrong interface; we might prefer to pass in the object type as
228 // well. It isn't important for this collector, but it might be for
229 // other collectors.
230 void *
231 _Jv_AllocObj (jsize size)
233 return GC_GENERIC_MALLOC (size, obj_kind_x);
236 // Allocate space for a new Java array. FIXME: again, this might be
237 // the wrong interface.
238 void *
239 _Jv_AllocArray (jsize size)
241 return GC_GENERIC_MALLOC (size, array_kind_x);
244 // Allocate some space that is known to be pointer-free.
245 void *
246 _Jv_AllocBytes (jsize size)
248 return GC_GENERIC_MALLOC (size, PTRFREE);
251 static void
252 call_finalizer (GC_PTR obj, GC_PTR client_data)
254 _Jv_FinalizerFunc *fn = (_Jv_FinalizerFunc *) client_data;
255 jobject jobj = (jobject) obj;
257 (*fn) (jobj);
260 void
261 _Jv_RegisterFinalizer (void *object, _Jv_FinalizerFunc *meth)
263 GC_REGISTER_FINALIZER_NO_ORDER (object, call_finalizer, meth,
264 NULL, NULL);
267 void
268 _Jv_RunFinalizers (void)
270 GC_invoke_finalizers ();
273 void
274 _Jv_RunAllFinalizers (void)
276 GC_finalize_all ();
279 void
280 _Jv_RunGC (void)
282 GC_gcollect ();
285 long
286 _Jv_GCTotalMemory (void)
288 return GC_get_heap_size ();
291 /* Sum size of each hblk. */
292 static void
293 sum_blocks (struct hblk *h, word arg)
295 long *sump = (long *) arg;
296 /* This evil computation is from boehm-gc/checksums.c. */
297 hdr *hhdr = HDR (h);
298 int bytes = WORDS_TO_BYTES (hhdr->hb_sz);
299 bytes += HDR_BYTES + HBLKSIZE - 1;
300 bytes &= ~ (HBLKSIZE - 1);
301 *sump += bytes;
304 /* This turns out to be expensive to implement. For now, we don't
305 care. We could make it less expensive, perhaps, but that would
306 require some changes to the collector. */
307 long
308 _Jv_GCFreeMemory (void)
310 long sum = 0;
311 GC_apply_to_all_blocks (sum_blocks, &sum);
312 return sum;
315 void
316 _Jv_InitGC (void)
318 int proc;
319 DCL_LOCK_STATE;
321 DISABLE_SIGNALS ();
322 LOCK ();
324 if (initialized)
326 UNLOCK ();
327 ENABLE_SIGNALS ();
328 return;
330 initialized = 1;
332 // Set up state for marking and allocation of Java objects.
333 obj_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1)
334 * sizeof (ptr_t),
335 PTRFREE);
336 memset (obj_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t));
338 proc = GC_n_mark_procs++;
339 GC_mark_procs[proc] = (mark_proc) _Jv_MarkObj;
341 obj_kind_x = GC_n_kinds++;
342 GC_obj_kinds[obj_kind_x].ok_freelist = obj_free_list;
343 GC_obj_kinds[obj_kind_x].ok_reclaim_list = 0;
344 GC_obj_kinds[obj_kind_x].ok_descriptor = MAKE_PROC (proc, 0);
345 GC_obj_kinds[obj_kind_x].ok_relocate_descr = FALSE;
346 GC_obj_kinds[obj_kind_x].ok_init = TRUE;
348 // Set up state for marking and allocation of arrays of Java
349 // objects.
350 array_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1)
351 * sizeof (ptr_t),
352 PTRFREE);
353 memset (array_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t));
355 proc = GC_n_mark_procs++;
356 GC_mark_procs[proc] = (mark_proc) _Jv_MarkArray;
358 array_kind_x = GC_n_kinds++;
359 GC_obj_kinds[array_kind_x].ok_freelist = array_free_list;
360 GC_obj_kinds[array_kind_x].ok_reclaim_list = 0;
361 GC_obj_kinds[array_kind_x].ok_descriptor = MAKE_PROC (proc, 0);
362 GC_obj_kinds[array_kind_x].ok_relocate_descr = FALSE;
363 GC_obj_kinds[array_kind_x].ok_init = TRUE;
365 UNLOCK ();
366 ENABLE_SIGNALS ();