]> gcc.gnu.org Git - gcc.git/blame - libjava/boehm.cc
All files: Updated copyright information.
[gcc.git] / libjava / boehm.cc
CommitLineData
ee9dd372
TT
1// boehm.cc - interface between libjava and Boehm GC.
2
2ba5f774 3/* Copyright (C) 1998, 1999, 2000 Free Software Foundation
ee9dd372
TT
4
5 This file is part of libgcj.
6
7This software is copyrighted work licensed under the terms of the
8Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9details. */
10
11#include <config.h>
12
13#include <stdio.h>
14
ee9dd372 15#include <jvm.h>
27e934d8
TT
16#include <gcj/cni.h>
17
18#include <java/lang/Class.h>
58eb6e7c 19#include <java-interp.h>
ee9dd372 20
657ac766
TT
21// More nastiness: the GC wants to define TRUE and FALSE. We don't
22// need the Java definitions (themselves a hack), so we undefine them.
23#undef TRUE
24#undef FALSE
25
ee9dd372
TT
26extern "C"
27{
ee9dd372
TT
28#include <gc_priv.h>
29#include <gc_mark.h>
30
31 // These aren't declared in any Boehm GC header.
32 void GC_finalize_all (void);
33 ptr_t GC_debug_generic_malloc (size_t size, int k, GC_EXTRA_PARAMS);
34};
35
36// FIXME: this should probably be defined in some GC header.
37#ifdef GC_DEBUG
38# define GC_GENERIC_MALLOC(Size, Type) \
39 GC_debug_generic_malloc (Size, Type, GC_EXTRAS)
40#else
41# define GC_GENERIC_MALLOC(Size, Type) GC_generic_malloc (Size, Type)
42#endif
43
44// We must check for plausibility ourselves.
45#define MAYBE_MARK(Obj, Top, Limit, Source, Exit) \
46 if ((ptr_t) (Obj) >= GC_least_plausible_heap_addr \
47 && (ptr_t) (Obj) <= GC_greatest_plausible_heap_addr) \
48 PUSH_CONTENTS (Obj, Top, Limit, Source, Exit)
49
50#define ObjectClass _CL_Q34java4lang6Object
51extern java::lang::Class ObjectClass;
52#define ClassClass _CL_Q34java4lang5Class
53extern java::lang::Class ClassClass;
54
55\f
56
57// Nonzero if this module has been initialized.
58static int initialized = 0;
59
60// `kind' index used when allocating Java objects.
61static int obj_kind_x;
62
63// `kind' index used when allocating Java arrays.
64static int array_kind_x;
65
66// Freelist used for Java objects.
67static ptr_t *obj_free_list;
68
69// Freelist used for Java arrays.
70static ptr_t *array_free_list;
71
72\f
73
74// This is called by the GC during the mark phase. It marks a Java
75// object. We use `void *' arguments and return, and not what the
76// Boehm GC wants, to avoid pollution in our headers.
77void *
78_Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
79{
80 mse *mark_stack_ptr = (mse *) msp;
81 mse *mark_stack_limit = (mse *) msl;
82 jobject obj = (jobject) addr;
83
84 _Jv_VTable *dt = *(_Jv_VTable **) addr;
85 // We check this in case a GC occurs before the vtbl is set. FIXME:
86 // should use allocation lock while initializing object.
87 if (! dt)
88 return mark_stack_ptr;
89 jclass klass = dt->clas;
90
91 // Every object has a sync_info pointer.
92 word w = (word) obj->sync_info;
93 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, o1label);
94 // Mark the object's class.
95 w = (word) klass;
96 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, o2label);
97
98 if (klass == &ClassClass)
99 {
100 jclass c = (jclass) addr;
101
58eb6e7c
AG
102#if 0
103 // The next field should probably not be marked, since this is
104 // only used in the class hash table. Marking this field
105 // basically prohibits class unloading. --Kresten
ee9dd372
TT
106 w = (word) c->next;
107 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c2label);
58eb6e7c
AG
108#endif
109
ee9dd372
TT
110 w = (word) c->name;
111 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c3label);
112 w = (word) c->superclass;
113 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c4label);
114 for (int i = 0; i < c->constants.size; ++i)
115 {
7941ceab
AG
116 /* FIXME: We could make this more precise by using the tags -KKT */
117 w = (word) c->constants.data[i].p;
ee9dd372
TT
118 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5label);
119 }
120
58eb6e7c
AG
121#ifdef INTERPRETER
122 if (_Jv_IsInterpretedClass (c))
123 {
124 w = (word) c->constants.tags;
125 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5alabel);
126 w = (word) c->constants.data;
127 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c5blabel);
128 }
129#endif
130
ee9dd372
TT
131 // If the class is an array, then the methods field holds a
132 // pointer to the element class. If the class is primitive,
133 // then the methods field holds a pointer to the array class.
134 w = (word) c->methods;
135 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c6label);
136
58eb6e7c 137
ee9dd372
TT
138 if (! c->isArray() && ! c->isPrimitive())
139 {
140 // Scan each method in the cases where `methods' really
141 // points to a methods structure.
142 for (int i = 0; i < c->method_count; ++i)
143 {
144 w = (word) c->methods[i].name;
145 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
146 cm1label);
147 w = (word) c->methods[i].signature;
148 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
149 cm2label);
58eb6e7c 150
ee9dd372 151 // FIXME: `ncode' entry?
58eb6e7c
AG
152
153#ifdef INTERPRETER
154 // The interpreter installs a heap-allocated
155 // trampoline here, so we'll mark it.
156 if (_Jv_IsInterpretedClass (c))
157 {
158 w = (word) c->methods[i].ncode;
159 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c,
160 cm3label);
161 }
162#endif
ee9dd372
TT
163 }
164 }
165
166 // Mark all the fields.
167 w = (word) c->fields;
168 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8label);
169 for (int i = 0; i < c->field_count; ++i)
170 {
58eb6e7c
AG
171 _Jv_Field* field = &c->fields[i];
172
ee9dd372 173#ifndef COMPACT_FIELDS
58eb6e7c 174 w = (word) field->name;
ee9dd372
TT
175 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8alabel);
176#endif
58eb6e7c 177 w = (word) field->type;
ee9dd372 178 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8blabel);
58eb6e7c
AG
179
180 // For the interpreter, we also need to mark the memory
181 // containing static members
182 if (field->flags & 0x0008)
183 {
184 w = (word) field->u.addr;
185 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c8clabel);
186
187 // also, if the static member is a reference,
188 // mark also the value pointed to. We check for isResolved
189 // since marking can happen before memory is allocated for
190 // static members.
191 if (JvFieldIsRef (field) && field->isResolved())
192 {
193 jobject val = *(jobject*) field->u.addr;
194 w = (word) val;
195 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit,
196 c, c8elabel);
197 }
198 }
ee9dd372
TT
199 }
200
201 w = (word) c->vtable;
202 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, c9label);
203 w = (word) c->interfaces;
204 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cAlabel);
205 for (int i = 0; i < c->interface_count; ++i)
206 {
207 w = (word) c->interfaces[i];
208 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cClabel);
209 }
210 w = (word) c->loader;
211 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, c, cBlabel);
58eb6e7c
AG
212
213#ifdef INTERPRETER
214 if (_Jv_IsInterpretedClass (c))
215 {
216 _Jv_InterpClass* ic = (_Jv_InterpClass*)c;
217
218 w = (word) ic->interpreted_methods;
219 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, ic, cElabel);
220
221 for (int i = 0; i < c->method_count; i++)
222 {
223 w = (word) ic->interpreted_methods[i];
224 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, ic, \
225 cFlabel);
226 }
227
228 w = (word) ic->field_initializers;
229 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, ic, cGlabel);
230
231 }
232#endif
233
ee9dd372
TT
234 }
235 else
236 {
237 // NOTE: each class only holds information about the class
238 // itself. So we must do the marking for the entire inheritance
239 // tree in order to mark all fields. FIXME: what about
240 // interfaces? We skip Object here, because Object only has a
241 // sync_info, and we handled that earlier.
242 // Note: occasionally `klass' can be null. For instance, this
243 // can happen if a GC occurs between the point where an object
244 // is allocated and where the vtbl slot is set.
245 while (klass && klass != &ObjectClass)
246 {
247 jfieldID field = JvGetFirstInstanceField (klass);
248 jint max = JvNumInstanceFields (klass);
249
250 for (int i = 0; i < max; ++i)
251 {
252 if (JvFieldIsRef (field))
253 {
254 jobject val = JvGetObjectField (obj, field);
255 w = (word) val;
256 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit,
257 obj, elabel);
258 }
8a922095 259 field = field->getNextField ();
ee9dd372
TT
260 }
261 klass = klass->getSuperclass();
262 }
263 }
264
265 return mark_stack_ptr;
266}
267
268// This is called by the GC during the mark phase. It marks a Java
269// array (of objects). We use `void *' arguments and return, and not
270// what the Boehm GC wants, to avoid pollution in our headers.
271void *
272_Jv_MarkArray (void *addr, void *msp, void *msl, void * /*env*/)
273{
274 mse *mark_stack_ptr = (mse *) msp;
275 mse *mark_stack_limit = (mse *) msl;
276 jobjectArray array = (jobjectArray) addr;
277
278 _Jv_VTable *dt = *(_Jv_VTable **) addr;
279 // We check this in case a GC occurs before the vtbl is set. FIXME:
280 // should use allocation lock while initializing object.
281 if (! dt)
282 return mark_stack_ptr;
283 jclass klass = dt->clas;
284
285 // Every object has a sync_info pointer.
286 word w = (word) array->sync_info;
287 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, array, e1label);
288 // Mark the object's class.
289 w = (word) klass;
290 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, obj, o2label);
291
292 for (int i = 0; i < JvGetArrayLength (array); ++i)
293 {
294 jobject obj = elements (array)[i];
295 w = (word) obj;
296 MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit, array, e2label);
297 }
298
299 return mark_stack_ptr;
300}
301
302// Allocate space for a new Java object. FIXME: this might be the
303// wrong interface; we might prefer to pass in the object type as
304// well. It isn't important for this collector, but it might be for
305// other collectors.
306void *
307_Jv_AllocObj (jsize size)
308{
309 return GC_GENERIC_MALLOC (size, obj_kind_x);
310}
311
312// Allocate space for a new Java array. FIXME: again, this might be
313// the wrong interface.
314void *
315_Jv_AllocArray (jsize size)
316{
317 return GC_GENERIC_MALLOC (size, array_kind_x);
318}
319
320// Allocate some space that is known to be pointer-free.
321void *
322_Jv_AllocBytes (jsize size)
323{
38b3a2c0
TT
324 void *r = GC_GENERIC_MALLOC (size, PTRFREE);
325 // We have to explicitly zero memory here, as the GC doesn't
326 // guarantee that PTRFREE allocations are zeroed. Note that we
327 // don't have to do this for other allocation types because we set
328 // the `ok_init' flag in the type descriptor.
329 if (r != NULL)
330 memset (r, 0, size);
331 return r;
ee9dd372
TT
332}
333
334static void
335call_finalizer (GC_PTR obj, GC_PTR client_data)
336{
337 _Jv_FinalizerFunc *fn = (_Jv_FinalizerFunc *) client_data;
338 jobject jobj = (jobject) obj;
339
340 (*fn) (jobj);
341}
342
343void
344_Jv_RegisterFinalizer (void *object, _Jv_FinalizerFunc *meth)
345{
25fef12b 346 GC_REGISTER_FINALIZER_NO_ORDER (object, call_finalizer, (GC_PTR) meth,
ee9dd372
TT
347 NULL, NULL);
348}
349
350void
351_Jv_RunFinalizers (void)
352{
353 GC_invoke_finalizers ();
354}
355
356void
357_Jv_RunAllFinalizers (void)
358{
359 GC_finalize_all ();
360}
361
362void
363_Jv_RunGC (void)
364{
365 GC_gcollect ();
366}
367
368long
369_Jv_GCTotalMemory (void)
370{
371 return GC_get_heap_size ();
372}
373
ee9dd372
TT
374long
375_Jv_GCFreeMemory (void)
376{
e40217a7 377 return GC_get_free_bytes ();
ee9dd372
TT
378}
379
b8c3c4f0
TT
380void
381_Jv_GCSetInitialHeapSize (size_t size)
382{
383 size_t current = GC_get_heap_size ();
384 if (size > current)
3948f9d0 385 GC_expand_hp (size - current);
b8c3c4f0
TT
386}
387
388void
389_Jv_GCSetMaximumHeapSize (size_t size)
390{
391 GC_set_max_heap_size ((GC_word) size);
392}
393
ee9dd372
TT
394void
395_Jv_InitGC (void)
396{
397 int proc;
398 DCL_LOCK_STATE;
399
400 DISABLE_SIGNALS ();
401 LOCK ();
402
403 if (initialized)
404 {
405 UNLOCK ();
406 ENABLE_SIGNALS ();
407 return;
408 }
409 initialized = 1;
410
e40217a7
TT
411 GC_java_finalization = 1;
412
ee9dd372
TT
413 // Set up state for marking and allocation of Java objects.
414 obj_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1)
415 * sizeof (ptr_t),
416 PTRFREE);
417 memset (obj_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t));
418
419 proc = GC_n_mark_procs++;
420 GC_mark_procs[proc] = (mark_proc) _Jv_MarkObj;
421
422 obj_kind_x = GC_n_kinds++;
423 GC_obj_kinds[obj_kind_x].ok_freelist = obj_free_list;
424 GC_obj_kinds[obj_kind_x].ok_reclaim_list = 0;
425 GC_obj_kinds[obj_kind_x].ok_descriptor = MAKE_PROC (proc, 0);
426 GC_obj_kinds[obj_kind_x].ok_relocate_descr = FALSE;
427 GC_obj_kinds[obj_kind_x].ok_init = TRUE;
428
429 // Set up state for marking and allocation of arrays of Java
430 // objects.
431 array_free_list = (ptr_t *) GC_generic_malloc_inner ((MAXOBJSZ + 1)
432 * sizeof (ptr_t),
433 PTRFREE);
434 memset (array_free_list, 0, (MAXOBJSZ + 1) * sizeof (ptr_t));
435
436 proc = GC_n_mark_procs++;
437 GC_mark_procs[proc] = (mark_proc) _Jv_MarkArray;
438
439 array_kind_x = GC_n_kinds++;
440 GC_obj_kinds[array_kind_x].ok_freelist = array_free_list;
441 GC_obj_kinds[array_kind_x].ok_reclaim_list = 0;
442 GC_obj_kinds[array_kind_x].ok_descriptor = MAKE_PROC (proc, 0);
443 GC_obj_kinds[array_kind_x].ok_relocate_descr = FALSE;
444 GC_obj_kinds[array_kind_x].ok_init = TRUE;
445
446 UNLOCK ();
447 ENABLE_SIGNALS ();
448}
This page took 0.125323 seconds and 5 git commands to generate.