Renamed loging to logging
[cacao.git] / src / mm / boehm.c
1 /* mm/boehm.c - interface for boehm gc
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Stefan Ring
28
29    $Id: boehm.c 1067 2004-05-18 10:25:51Z stefan $
30
31 */
32
33 #if defined(USE_THREADS) && defined(NATIVE_THREADS) && defined(__LINUX__)
34 #define GC_LINUX_THREADS
35 #endif
36
37 #include "main.h"
38 #include "boehm.h"
39 #include "global.h"
40 #include "native.h"
41 #include "asmpart.h"
42 #include "builtin.h"
43 #include "threads/thread.h"
44 #include "toolbox/logging.h"
45 #include "gc.h"
46
47
48 static void *stackcall_twoargs(struct otherstackcall *p)
49 {
50         return (*p->p2)(p->p, p->l);
51 }
52
53
54 static void *stackcall_malloc(void *p, u4 bytelength)
55 {
56         return GC_MALLOC(bytelength);
57 }
58
59
60 static void *stackcall_malloc_atomic(void *p, u4 bytelength)
61 {
62         return GC_MALLOC_ATOMIC(bytelength);
63 }
64
65
66 static void *stackcall_malloc_uncollectable(void *p, u4 bytelength)
67 {
68         return GC_MALLOC_UNCOLLECTABLE(bytelength);
69 }
70
71
72 static void *stackcall_realloc(void *p, u4 bytelength)
73 {
74         return GC_REALLOC(p, bytelength);
75 }
76
77 static void *stackcall_free(void *p, u4 bytelength)
78 {
79         GC_FREE(p);
80         return NULL;
81 }
82
83
84 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
85 #define MAINTHREADCALL(r,m,pp,ll) \
86         if (currentThread == NULL || currentThread == mainThread) { \
87                 r = m(pp, ll); \
88         } else { \
89                 struct otherstackcall sc; \
90                 sc.p2 = m; \
91                 sc.p = pp; \
92                 sc.l = ll; \
93                 r = (*asm_switchstackandcall)(CONTEXT(mainThread).usedStackTop, \
94                                 stackcall_twoargs, \
95                                 (void**)&(CONTEXT(currentThread).usedStackTop), &sc); \
96         }
97 #else
98 #define MAINTHREADCALL(r,m,pp,ll) \
99         { r = m(pp, ll); }
100 #endif
101
102
103 void *heap_alloc_uncollectable(u4 bytelength)
104 {
105         void *result;
106         MAINTHREADCALL(result, stackcall_malloc_uncollectable, NULL, bytelength);
107         return result;
108 }
109
110
111 void runboehmfinalizer(void *o, void *p)
112 {
113         java_objectheader *ob = (java_objectheader *) o;
114
115         asm_calljavafunction(ob->vftbl->class->finalizer, ob, NULL, NULL, NULL);
116         
117         /* if we had an exception in the finalizer, ignore it */
118         *exceptionptr = NULL;
119 }
120
121
122 void *heap_allocate(u4 bytelength, bool references, methodinfo *finalizer)
123 {
124         void *result;
125
126         if (references) {
127                 MAINTHREADCALL(result, stackcall_malloc, NULL, bytelength);
128
129         } else {
130                 MAINTHREADCALL(result, stackcall_malloc_atomic, NULL, bytelength);
131         }
132
133         if (!result) {
134                 return NULL;
135         }
136
137         if (finalizer)
138                 GC_REGISTER_FINALIZER(result, runboehmfinalizer, 0, 0, 0);
139
140         return (u1*) result;
141 }
142
143
144 void *heap_reallocate(void *p, u4 bytelength)
145 {
146         void *result;
147
148         MAINTHREADCALL(result, stackcall_realloc, p, bytelength);
149
150         return result;
151 }
152
153 void heap_free(void *p)
154 {
155         void *result;
156
157         MAINTHREADCALL(result, stackcall_free, p, 0);
158 }
159
160
161 void gc_init(u4 heapmaxsize, u4 heapstartsize)
162 {
163         size_t heapcurrentsize;
164
165         GC_init();
166
167         /* set the maximal heap size */
168         GC_set_max_heap_size(heapmaxsize);
169
170         /* set the initial heap size */
171         heapcurrentsize = GC_get_heap_size();
172         if (heapstartsize > heapcurrentsize) {
173                 GC_expand_hp(heapstartsize - heapcurrentsize);
174         }
175
176         /* define OOM function */
177         GC_oom_fn = gc_out_of_memory;
178 }
179
180
181 void gc_call()
182 {
183         if (collectverbose)
184                 dolog("Garbage Collection:  previous/now = %d / %d ",
185                           0, 0);
186
187         GC_gcollect();
188 }
189
190
191 s8 gc_get_heap_size()
192 {
193         return GC_get_heap_size();
194 }
195
196
197 s8 gc_get_free_bytes()
198 {
199         return GC_get_free_bytes();
200 }
201
202
203 s8 gc_get_max_heap_size()
204 {
205         return GC_get_max_heap_size();
206 }
207
208
209 void gc_finalize_all()
210 {
211         GC_finalize_all();
212 }
213
214
215 /* This function is called when boehm detects that it is OOM */
216
217 void *gc_out_of_memory()
218 {
219         static bool in_gc_out_of_memory;
220
221         /* if this happens, we are REALLY out of memory */
222         if (in_gc_out_of_memory) {
223                 /* this is all we can do... */
224                 printf("Exception in thread \"main\" java.lang.OutOfMemoryError\n");
225                 fflush(stdout);
226                 exit(1);
227         }
228
229         in_gc_out_of_memory = true;
230
231         *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
232
233         in_gc_out_of_memory = false;
234
235         return NULL;
236 }
237
238
239 /*
240  * These are local overrides for various environment variables in Emacs.
241  * Please do not remove this and leave it at the end of the file, where
242  * Emacs will automagically detect them.
243  * ---------------------------------------------------------------------
244  * Local variables:
245  * mode: c
246  * indent-tabs-mode: t
247  * c-basic-offset: 4
248  * tab-width: 4
249  * End:
250  */