Line data Source code
1 : /* src/mm/gc-boehm.cpp - interface for boehm gc
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 : #include "mm/gc.hpp"
26 : #include <stddef.h> // for size_t, NULL
27 : #include <stdint.h> // for int64_t, uint8_t
28 : #include "config.h"
29 : #include "mm/memory.hpp" // for MSET
30 : #include "toolbox/logging.hpp" // for dolog
31 : #include "vm/exceptions.hpp"
32 : #include "vm/finalizer.hpp" // for finalizer_notify, etc
33 : #include "vm/options.hpp"
34 : #include "vm/os.hpp" // for os
35 : #include "vm/rt-timing.hpp" // for RT_REGISTER_GROUP, etc
36 :
37 : #include "gc-boehm.hpp"
38 : #include "boehm-gc/include/javaxfc.h" // for GC_finalize_all
39 :
40 : struct methodinfo;
41 :
42 : /* global variables ***********************************************************/
43 :
44 : static bool in_gc_out_of_memory = false; /* is GC out of memory? */
45 : static size_t gc_max_heap_size = 0;
46 :
47 :
48 : /* prototype static functions *************************************************/
49 :
50 : static void gc_ignore_warnings(char *msg, GC_word arg);
51 :
52 :
53 : /* gc_init *********************************************************************
54 :
55 : Initializes the boehm garbage collector.
56 :
57 : *******************************************************************************/
58 :
59 163 : void gc_init(size_t heapmaxsize, size_t heapstartsize)
60 : {
61 : size_t heapcurrentsize;
62 :
63 163 : TRACESUBSYSTEMINITIALIZATION("gc_init");
64 :
65 : /* just to be sure (should be set to 1 by JAVA_FINALIZATION macro) */
66 :
67 163 : GC_java_finalization = 1;
68 :
69 : /* Ignore pointers that do not point to the start of an object. */
70 :
71 163 : GC_all_interior_pointers = 0;
72 :
73 : /* suppress warnings */
74 :
75 163 : GC_set_warn_proc(gc_ignore_warnings);
76 :
77 : /* install a GC notifier */
78 :
79 163 : GC_finalize_on_demand = 1;
80 163 : GC_finalizer_notifier = finalizer_notify;
81 :
82 : /* define OOM function */
83 :
84 163 : GC_oom_fn = gc_out_of_memory;
85 :
86 163 : GC_INIT();
87 :
88 : /* set the maximal heap size */
89 :
90 163 : GC_set_max_heap_size(heapmaxsize);
91 163 : gc_max_heap_size = heapmaxsize;
92 :
93 : /* set the initial heap size */
94 :
95 163 : heapcurrentsize = GC_get_heap_size();
96 :
97 163 : if (heapstartsize > heapcurrentsize)
98 163 : GC_expand_hp(heapstartsize - heapcurrentsize);
99 163 : }
100 :
101 :
102 3 : static void gc_ignore_warnings(char *msg, GC_word arg)
103 : {
104 3 : }
105 :
106 :
107 69101 : void *heap_alloc_uncollectable(size_t size)
108 : {
109 : void *p;
110 :
111 69101 : p = GC_MALLOC_UNCOLLECTABLE(size);
112 :
113 : /* clear allocated memory region */
114 :
115 69101 : MSET(p, 0, uint8_t, size);
116 :
117 69101 : return p;
118 : }
119 :
120 :
121 : // register heap timer
122 : RT_REGISTER_GROUP(heap_group,"heap","heap time")
123 : // register heap timer
124 : RT_REGISTER_GROUP_TIMER(heap_timer,"heap","allocation time",heap_group)
125 :
126 : /* heap_alloc ******************************************************************
127 :
128 : Allocates memory on the Java heap.
129 :
130 : *******************************************************************************/
131 :
132 2017775 : void *heap_alloc(size_t size, int references, methodinfo *finalizer, bool collect)
133 : {
134 : void *p;
135 :
136 : RT_TIMER_START(heap_timer);
137 :
138 : /* We can't use a bool here for references, as it's passed as a
139 : bitmask in builtin_new. Thus we check for != 0. */
140 :
141 2017775 : if (references != 0)
142 1437417 : p = GC_MALLOC(size);
143 : else
144 580358 : p = GC_MALLOC_ATOMIC(size);
145 :
146 2017775 : if (p == NULL)
147 3 : return NULL;
148 :
149 2017772 : if (finalizer != NULL)
150 23453 : GC_REGISTER_FINALIZER_NO_ORDER(p, finalizer_run, 0, 0, 0);
151 :
152 : /* clear allocated memory region */
153 :
154 2017772 : MSET(p, 0, uint8_t, size);
155 :
156 : RT_TIMER_STOP(heap_timer);
157 :
158 2017772 : return p;
159 : }
160 :
161 :
162 0 : void heap_free(void *p)
163 : {
164 0 : GC_FREE(p);
165 0 : }
166 :
167 5 : void gc_call(void)
168 : {
169 5 : if (opt_verbosegc)
170 : dolog("Garbage Collection: previous/now = %d / %d ",
171 0 : 0, 0);
172 :
173 5 : GC_gcollect();
174 5 : }
175 :
176 :
177 0 : int64_t gc_get_heap_size(void)
178 : {
179 0 : return GC_get_heap_size();
180 : }
181 :
182 :
183 0 : int64_t gc_get_free_bytes(void)
184 : {
185 0 : return GC_get_free_bytes();
186 : }
187 :
188 :
189 : /* gc_get_total_bytes **********************************************************
190 :
191 : Returns the number of total bytes currently used on the Java heap.
192 :
193 : *******************************************************************************/
194 :
195 0 : int64_t gc_get_total_bytes(void)
196 : {
197 0 : return GC_get_total_bytes();
198 : }
199 :
200 :
201 1 : int64_t gc_get_max_heap_size(void)
202 : {
203 1 : return gc_max_heap_size;
204 : }
205 :
206 :
207 55 : void gc_invoke_finalizers(void)
208 : {
209 55 : GC_invoke_finalizers();
210 55 : }
211 :
212 :
213 0 : void gc_finalize_all(void)
214 : {
215 0 : GC_finalize_all();
216 0 : }
217 :
218 :
219 : /* gc_out_of_memory ************************************************************
220 :
221 : This function is called when boehm detects that it is OOM.
222 :
223 : *******************************************************************************/
224 :
225 3 : void *gc_out_of_memory(size_t bytes_requested)
226 : {
227 : /* if this happens, we are REALLY out of memory */
228 :
229 3 : if (in_gc_out_of_memory) {
230 : /* this is all we can do... */
231 0 : os::abort("gc_out_of_memory: out of memory");
232 : }
233 :
234 3 : in_gc_out_of_memory = true;
235 :
236 : /* try to release some memory */
237 :
238 3 : gc_call();
239 :
240 : /* now instantiate the exception */
241 :
242 3 : exceptions_throw_outofmemoryerror();
243 :
244 3 : in_gc_out_of_memory = false;
245 :
246 3 : return NULL;
247 : }
248 :
249 0 : void gc_register_current_thread()
250 : {
251 : #ifdef ENABLE_THREADS
252 : // Register the thread with Boehm-GC.
253 : // This must happen before the thread allocates any memory from the GC heap.
254 :
255 : struct GC_stack_base sb;
256 :
257 0 : if (GC_get_stack_base(&sb) != GC_SUCCESS)
258 0 : vm_abort("threads_attach_current_thread: GC_get_stack_base failed");
259 :
260 0 : GC_register_my_thread(&sb);
261 : #endif
262 0 : }
263 :
264 0 : void gc_unregister_current_thread()
265 : {
266 : #ifdef ENABLE_THREADS
267 0 : GC_unregister_my_thread();
268 : #endif
269 0 : }
270 :
271 :
272 : /*
273 : * These are local overrides for various environment variables in Emacs.
274 : * Please do not remove this and leave it at the end of the file, where
275 : * Emacs will automagically detect them.
276 : * ---------------------------------------------------------------------
277 : * Local variables:
278 : * mode: c++
279 : * indent-tabs-mode: t
280 : * c-basic-offset: 4
281 : * tab-width: 4
282 : * End:
283 : * vim:noexpandtab:sw=4:ts=4:
284 : */
|