* src/native/jni.c (native/include/java_lang_Byte.h,
[cacao.git] / src / mm / cacao-gc / mark.c
1 /* mm/cacao-gc/mark.c - GC module for marking heap objects
2
3    Copyright (C) 1996-2005, 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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Michael Starzinger
28
29
30 */
31
32
33 #include "config.h"
34
35 #include "heap.h"
36 #include "toolbox/logging.h"
37 #include "vm/global.h"
38 #include "vm/linker.h"
39 #include "vm/options.h"
40
41
42 /* Debugging ******************************************************************/
43
44 int mark_depth;
45 int mark_depth_max;
46 #define MARK_DEPTH_INIT { mark_depth = 0; mark_depth_max = 0; }
47 #define MARK_DEPTH_INC { mark_depth++; if (mark_depth>mark_depth_max) mark_depth_max=mark_depth; }
48 #define MARK_DEPTH_DEC { mark_depth--; GC_ASSERT(mark_depth >= 0); }
49 void mark_println_stats()
50 {
51         printf("Maximal marking depth: %d\n", mark_depth_max);
52 }
53
54
55 /* mark_recursice **************************************************************
56
57    Recursively mark all objects (including this) which are referenced.
58
59    IN:
60           o.....heap-object to be marked (either OBJECT or ARRAY)
61
62 *******************************************************************************/
63
64 void mark_recursive(java_objectheader *o)
65 {
66         vftbl_t           *t;
67         classinfo         *c;
68         fieldinfo         *f;
69         java_objectarray  *oa;
70         arraydescriptor   *desc;
71         java_objectheader *ref;
72         int i;
73
74         /* uncollectable objects should never get marked this way */
75         GC_ASSERT(o);
76         GC_ASSERT(!GC_TEST_FLAGS(o, GC_FLAG_UNCOLLECTABLE));
77
78         /* mark this object */
79         GC_SET_MARKED(o);
80
81         /* get the class of this object */
82         /* TODO: maybe we do not need this yet, look to move down! */
83         t = o->vftbl;
84         GC_ASSERT(t);
85         c = t->class;
86         GC_ASSERT(c);
87
88         /* TODO: should we mark the class of the object as well? */
89         /*GC_ASSERT(GC_IS_MARKED((java_objectheader *) c));*/
90
91         /* does this object has pointers? */
92         /* TODO: check how often this happens, maybe remove this check! */
93         /*if (!GC_IS_REFERENCING(o))
94                 return;*/
95
96         /* check if we are marking an array */
97         if ((desc = t->arraydesc) != NULL) {
98                 /* this is an ARRAY */
99
100                 /* check if the array contains references */
101                 if (desc->arraytype != ARRAYTYPE_OBJECT)
102                         return;
103
104                 /* for object-arrays we need to check every entry */
105                 oa = (java_objectarray *) o;
106                 for (i = 0; i < oa->header.size; i++) {
107
108                         /* load the reference value */
109                         ref = (java_objectheader *) (oa->data[i]);
110
111                         /* check for outside or null pointers */
112                         if (!POINTS_INTO(ref, heap_base, heap_ptr))
113                                 continue;
114
115                         GC_LOG( printf("Found (%p) from Array\n", (void *) ref); );
116
117                         /* do the recursive marking */
118                         if (!GC_IS_MARKED(ref)) {
119                                 MARK_DEPTH_INC;
120                                 mark_recursive(ref);
121                                 MARK_DEPTH_DEC;
122                         }
123
124                 }
125
126         } else {
127                 /* this is an OBJECT */
128
129                 /* for objects we need to check all (non-static) fields */
130                 for (i = 0; i < c->fieldscount; i++) {
131                         f = &(c->fields[i]);
132
133                         /* check if this field contains a non-static reference */
134                         if (!IS_ADR_TYPE(f->type) || (f->flags & ACC_STATIC))
135                                 continue;
136
137                         /* load the reference value */
138                         ref = *( (java_objectheader **) ((s1 *) o + f->offset) );
139
140                         /* check for outside or null pointers */
141                         if (!POINTS_INTO(ref, heap_base, heap_ptr))
142                                 continue;
143
144                         GC_LOG( printf("Found (%p) from Field ", (void *) ref);
145                                         field_print(f); printf("\n"); );
146
147                         /* do the recursive marking */
148                         if (!GC_IS_MARKED(ref)) {
149                                 MARK_DEPTH_INC;
150                                 mark_recursive(ref);
151                                 MARK_DEPTH_DEC;
152                         }
153
154                 }
155
156         }
157
158 }
159
160
161 /* mark ************************************************************************
162
163    Marks all Heap Objects which are reachable from a given root-set.
164
165 *******************************************************************************/
166
167 /* rootset is passed as array of pointers, which point to the location of
168    the reference */
169 /* TODO: this definitely has to change!!! */
170 typedef java_objectheader** rootset_t;
171
172 void mark(rootset_t *rootset, int rootset_size)
173 {
174         java_objectheader *ref;
175         int i;
176
177         /* recursively mark all references of the rootset */
178         MARK_DEPTH_INIT;
179         MARK_DEPTH_INC;
180         for (i = 0; i < rootset_size; i++) {
181
182                 ref = *( rootset[i] );
183                 mark_recursive(ref);
184
185         }
186         MARK_DEPTH_DEC;
187         GC_ASSERT(mark_depth == 0);
188         GC_ASSERT(mark_depth_max > 0);
189
190         GC_LOG( mark_println_stats(); );
191 }
192
193
194 /*
195  * These are local overrides for various environment variables in Emacs.
196  * Please do not remove this and leave it at the end of the file, where
197  * Emacs will automagically detect them.
198  * ---------------------------------------------------------------------
199  * Local variables:
200  * mode: c
201  * indent-tabs-mode: t
202  * c-basic-offset: 4
203  * tab-width: 4
204  * End:
205  * vim:noexpandtab:sw=4:ts=4:
206  */