1 /* mm/cacao-gc/mark.c - GC module for marking heap objects
3 Copyright (C) 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "mm/memory.h"
38 #include "toolbox/logging.h"
39 #include "vm/global.h"
41 #include "vmcore/linker.h"
44 /* Helper Macros **************************************************************/
47 GCSTAT_COUNT_MAX(gcstat_mark_depth, gcstat_mark_depth_max); \
49 GCSTAT_DEC(gcstat_mark_depth);
52 /* mark_recursive **************************************************************
54 Recursively mark all objects (including this) which are referenced.
56 TODO, XXX: We need to implement a non-recursive version of this!!!
59 o.....heap-object to be marked (either OBJECT or ARRAY)
61 *******************************************************************************/
63 void mark_recursive(java_object_t *o)
68 java_objectarray_t *oa;
69 arraydescriptor *desc;
74 /* TODO: this needs cleanup!!! */
75 start = heap_region_main->base;
76 end = heap_region_main->ptr;
78 /* uncollectable objects should never get marked this way */
79 /* the reference should point into the heap */
81 GC_ASSERT(!GC_TEST_FLAGS(o, HDRFLAG_UNCOLLECTABLE));
82 GC_ASSERT(POINTS_INTO(o, start, end));
84 /* mark this object */
86 GCSTAT_COUNT(gcstat_mark_count);
88 /* get the class of this object */
89 /* TODO: maybe we do not need this yet, look to move down! */
95 #if defined(GCCONF_HDRFLAG_REFERENCING)
96 /* does this object has pointers? */
97 /* TODO: check how often this happens, maybe remove this check! */
98 if (!GC_TEST_FLAGS(o, HDRFLAG_REFERENCING))
102 /* check if we are marking an array */
103 if ((desc = t->arraydesc) != NULL) {
104 /* this is an ARRAY */
106 /* check if the array contains references */
107 if (desc->arraytype != ARRAYTYPE_OBJECT)
110 /* for object-arrays we need to check every entry */
111 oa = (java_objectarray_t *) o;
112 for (i = 0; i < oa->header.size; i++) {
114 /* load the reference value */
115 ref = (java_object_t *) (oa->data[i]);
117 /* check for outside or null pointers */
118 if (!POINTS_INTO(ref, start, end))
121 GC_LOG2( printf("Found (%p) from Array\n", (void *) ref); );
123 /* do the recursive marking */
124 if (!GC_IS_MARKED(ref)) {
125 GCSTAT_COUNT_MAX(gcstat_mark_depth, gcstat_mark_depth_max);
127 GCSTAT_DEC(gcstat_mark_depth);
133 /* this is an OBJECT */
135 /* for objects we need to check all (non-static) fields */
136 for (; c; c = c->super.cls) {
137 for (i = 0; i < c->fieldscount; i++) {
140 /* check if this field contains a non-static reference */
141 if (!IS_ADR_TYPE(f->type) || (f->flags & ACC_STATIC))
144 /* load the reference value */
145 ref = *( (java_object_t **) ((s1 *) o + f->offset) );
147 /* check for outside or null pointers */
148 if (!POINTS_INTO(ref, start, end))
151 GC_LOG2( printf("Found (%p) from Field ", (void *) ref);
152 field_print(f); printf("\n"); );
154 /* do the recursive marking */
155 if (!GC_IS_MARKED(ref)) {
156 GCSTAT_COUNT_MAX(gcstat_mark_depth, gcstat_mark_depth_max);
158 GCSTAT_DEC(gcstat_mark_depth);
169 /* mark_classes ****************************************************************
171 Marks all the references from classinfo structures (static fields)
174 start.....Region to be marked starts here
175 end.......Region to be marked ends here
177 *******************************************************************************/
179 void mark_classes(void *start, void *end)
184 void *sys_start, *sys_end;
187 GC_LOG( dolog("GC: Marking from classes ..."); );
189 /* TODO: cleanup!!! */
190 sys_start = heap_region_sys->base;
191 sys_end = heap_region_sys->ptr;
193 /* walk through all classinfo blocks */
194 for (c = sys_start; c < (classinfo *) sys_end; c++) {
196 /* walk through all fields */
198 for (i = 0; i < c->fieldscount; i++, f++) {
200 /* check if this is a static reference */
201 if (!IS_ADR_TYPE(f->type) || !(f->flags & ACC_STATIC))
204 /* load the reference */
205 ref = (java_object_t *) (f->value);
207 /* check for outside or null pointers */
208 if (!POINTS_INTO(ref, start, end))
211 /* mark the reference */
221 /* mark_me *********************************************************************
223 Marks all Heap Objects which are reachable from a given root-set.
225 REMEMBER: Assumes all threads are stopped!
228 rs.....root set containing the references
230 *******************************************************************************/
232 void mark_me(rootset_t *rs)
235 #if defined(GCCONF_FINALIZER)
236 list_final_entry_t *fe;
242 /* TODO: this needs cleanup!!! */
243 start = heap_region_main->base;
244 end = heap_region_main->ptr;
246 GCSTAT_INIT(gcstat_mark_count);
247 GCSTAT_INIT(gcstat_mark_depth);
248 GCSTAT_INIT(gcstat_mark_depth_max);
250 /* recursively mark all references from classes */
251 /*mark_classes(heap_region_main->base, heap_region_main->ptr);*/
254 GC_LOG( dolog("GC: Marking from rootset (%d entries) ...", rs->refcount); );
256 /* mark all references of the rootset */
257 for (i = 0; i < rs->refcount; i++) {
259 /* is this a marking reference? */
260 if (!rs->refs[i].marks)
263 /* load the reference */
264 ref = *( rs->refs[i].ref );
266 /* check for outside or null pointers */
267 if (!POINTS_INTO(ref, start, end))
270 /* do the marking here */
278 #if defined(GCCONF_FINALIZER)
279 /* objects with finalizers will also be marked here. if they have not been
280 * marked before the finalization is triggered */
281 /* REMEMBER: all threads are stopped, so we can use unsynced access here */
282 fe = list_first_unsynced(final_list);
287 /* we do not care about objects which have been marked already */
288 if (!GC_IS_MARKED(ref)) {
292 case FINAL_REACHABLE: /* object was reachable before */
293 GC_LOG2( printf("Finalizer triggered for: ");
294 heap_print_object(ref); printf("\n"); );
296 /* object is now reclaimable */
297 fe->type = FINAL_RECLAIMABLE;
299 /* notify the finalizer after collection finished */
300 gc_notify_finalizer = true;
302 /* keep the object alive until finalizer finishes */
306 case FINAL_RECLAIMABLE: /* object not yet finalized */
307 GC_LOG( printf("Finalizer not yet started for: ");
308 heap_print_object(ref); printf("\n"); );
310 /* keep the object alive until finalizer finishes */
315 case FINAL_FINALIZING: /* object is still being finalized */
316 GC_LOG( printf("Finalizer not yet finished for: ");
317 heap_print_object(ref); printf("\n"); );
319 /* keep the object alive until finalizer finishes */
324 default: /* case not yet covered */
325 vm_abort("mark_me: uncovered case (type=%d)", f_type);
330 fe = list_next_unsynced(final_list, fe);
332 #endif /*defined(GCCONF_FINALIZER)*/
334 GC_LOG( dolog("GC: Marking finished."); );
336 #if defined(ENABLE_STATISTICS)
337 GC_ASSERT(gcstat_mark_depth == 0);
343 * These are local overrides for various environment variables in Emacs.
344 * Please do not remove this and leave it at the end of the file, where
345 * Emacs will automagically detect them.
346 * ---------------------------------------------------------------------
349 * indent-tabs-mode: t
353 * vim:noexpandtab:sw=4:ts=4: