* configure.ac: Define automake conditinal ENABLE_TLH if SSA enabled.
[cacao.git] / src / mm / cacao-gc / copy.c
1 /* mm/cacao-gc/copy.c - GC module for copying heap regions
2
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
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 */
26
27
28 #include "config.h"
29 #include "vm/types.h"
30
31 #include "gc.h"
32 #include "heap.h"
33 #include "mark.h"
34 #include "region.h"
35 #include "rootset.h"
36 #include "mm/memory.h"
37 #include "toolbox/logging.h"
38 #include "vm/global.h"
39
40
41 /* Global Variables ***********************************************************/
42
43 static java_object_t *next;
44
45
46 static u4 copy_object(u1 *old, u1 *new, u4 size)
47 {
48         u4 new_size;
49
50         GC_LOG2( printf("\tcopy_object: %p -> %p\n", old, new); );
51
52         /* copy old object content to new location */
53         MCOPY(new, old, u1, size);
54
55         /* invalidate old object */
56         /* TODO: implement me, but remember not to destroy the header! */
57
58         new_size = size;
59
60         /* check if we need to attach the hashcode to the object */
61         if (GC_TEST_FLAGS((java_object_t *) new, HDRFLAG_HASH_TAKEN)) {
62
63                 GC_LOG( printf("need to attach hash to %p\n", new); );
64
65         }
66
67         return new_size;
68 }
69
70
71 #define GC_FORWARD(ref,refptr,start,end) \
72         *(refptr) = copy_forward(ref, start, end)
73
74 static void *copy_forward(java_object_t *o, void *src_start, void *src_end)
75 {
76         s4 o_size;
77
78         /* TODO: this is only to make debug output more readable; remove me! */
79         if (o == NULL)
80                 return NULL;
81
82         if (POINTS_INTO(o, src_start, src_end)) {
83
84                 /* update all references which point into the source region */
85
86                 /* NOTE: we use the marking bit here to mark object which have already
87                  * been copied; in such a case the *vftbl contains the location of
88                  * the copy */ 
89                 if (GC_IS_MARKED(o)) {
90
91                         GC_LOG2( printf("\tForwarding reference: %p -> ", (void *) o);
92                                         heap_print_object((java_object_t *) o->vftbl);
93                                         printf("\n"); );
94
95                         /* return the location of an already existing copy */
96                         return o->vftbl;
97
98                 } else {
99
100                         GC_LOG2( printf("\tCopying object to %p: ", (void *) next);
101                                         heap_print_object(o); printf("\n"); );
102
103                         /* calculate the size of the object to be copied */
104                         o_size = get_object_size(o);
105
106                         /* copy the object pointed to by O to location NEXT */
107                         o_size = copy_object(o, next, o_size);
108
109                         /* remember where the copy is located and mark original */
110                         GC_SET_MARKED(o);
111                         o->vftbl = (void *) next;
112
113                         /* increment NEXT to point past the copy of the object */
114                         next = ((u1 *) next) + o_size;
115
116                         /* return the location of the copy */
117                         return o->vftbl;
118
119                 }
120
121         } else {
122
123                 GC_LOG2( printf("\tDoing nothing for outside reference: ");
124                                 heap_print_object(o); printf("\n"); );
125
126                 /* do not change references not pointing into the source region */
127                 return o;
128
129         }
130 }
131
132
133 void copy_me(regioninfo_t *src, regioninfo_t *dst, rootset_t *rs)
134 {
135         java_object_t  *scan;
136         /*java_object_t *next;*/
137         java_object_t  *ref;
138         java_object_t **refptr;
139         int i;
140
141         /* initialize the scan and next pointer */
142         scan = (java_object_t *) dst->base;
143         next = (java_object_t *) dst->base;
144
145         GC_LOG( dolog("GC: Copying object from rootset ..."); );
146
147         /* for each root pointer R: replace R with forward(R) */
148         while (rs) {
149                 for (i = 0; i < rs->refcount; i++) {
150
151                         /* load the root reference */
152                         ref = *( rs->refs[i].ref );
153
154                         /* forward the object */
155                         GC_FORWARD(ref, rs->refs[i].ref, src->base, src->end);
156
157                 }
158
159                 rs = rs->next;
160         }
161
162         GC_LOG( dolog("GC: Copying referenced objects ...") );
163
164         /* update all references for objects in the destination region.
165          * when scan catches up with next, the algorithm is finished */
166         while (scan < next)
167         {
168
169                 GC_LOG2( printf("Will also forward reference in ");
170                                 heap_print_object(scan); printf("\n"); );
171
172                 if (IS_ARRAY(scan)) {
173
174                         /* walk through the references of an Array */
175                         FOREACH_ARRAY_REF(scan,ref,refptr,
176
177                                 GC_FORWARD(ref, refptr, src->base, src->end);
178
179                         );
180
181                 } else {
182
183                         /* walk through the references of an Object */
184                         FOREACH_OBJECT_REF(scan,ref,refptr,
185
186                                 GC_FORWARD(ref, refptr, src->base, src->end);
187
188                         );
189
190                 }
191
192                 scan = ((u1 *) scan) + get_object_size(scan); 
193         }
194
195         /* update destination region information */
196         /* TODO: there is more to update! */
197         dst->ptr = scan;
198
199         /* some basic assumptions */
200         GC_ASSERT(scan == next);
201         GC_ASSERT(scan < dst->end);
202 }
203
204
205 /*
206  * These are local overrides for various environment variables in Emacs.
207  * Please do not remove this and leave it at the end of the file, where
208  * Emacs will automagically detect them.
209  * ---------------------------------------------------------------------
210  * Local variables:
211  * mode: c
212  * indent-tabs-mode: t
213  * c-basic-offset: 4
214  * tab-width: 4
215  * End:
216  * vim:noexpandtab:sw=4:ts=4:
217  */